手写区块链(二):区块链开发中的密码学知识

手写区块链中会采用各种密码学知识

对称加密-加密秘钥和解密秘钥是同一个,缺点是秘钥无法被安全传递,常用的对称加密算法有

DES,3DES(TripleDES),AES

非对称加密-公钥加密,私钥解密

公钥由私钥生成,私钥可以推导出公钥,公钥无法推导出私钥。优点:解决秘钥传输中的安全行问题。

常用算法RSA,ECC

如何验证发送方是正确的

哈希:将一段数据经过计算转换成一段定长数据

不可逆性:几乎无法通过哈希推导出原文

无碰撞性:两个不同的原文hash后值一定不一样

常用算法MD5,SHA256

数字签名

公私钥对,私钥签名,公钥解签名

下面是这几个签名算法的具体java实现

package com.fj.blockchainmy.security;

import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;

import javax.crypto.KeyGenerator;import javax.crypto.Mac;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import java.security.MessageDigest;

/** * @author: yangchun * @description: * @date: Created in 2019-11-12 15:38 */public class Coder {    public static final String KEY_SHA = "SHA";    public static final String KEY_MD5 = "MD5";

    /**     * MAC算法可选以下多种算法     *     * <pre>     * HmacMD5     * HmacSHA1     * HmacSHA256     * HmacSHA384     * HmacSHA512     * </pre>     */    public static final String KEY_MAC = "HmacMD5";

    /**     * BASE64解密     *     * @param key     * @return     * @throws Exception     */    public static byte[] decryptBASE64(String key) throws Exception {        return (new BASE64Decoder()).decodeBuffer(key);    }

    /**     * BASE64加密     *     * @param key     * @return     * @throws Exception     */    public static String encryptBASE64(byte[] key) throws Exception {        return (new BASE64Encoder()).encodeBuffer(key);    }

    /**     * MD5加密     *     * @param data     * @return     * @throws Exception     */    public static byte[] encryptMD5(byte[] data) throws Exception {

        MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);        md5.update(data);

        return md5.digest();

    }

    /**     * SHA加密     *     * @param data     * @return     * @throws Exception     */    public static byte[] encryptSHA(byte[] data) throws Exception {

        MessageDigest sha = MessageDigest.getInstance(KEY_SHA);        sha.update(data);

        return sha.digest();

    }

    /**     * 初始化HMAC密钥     *     * @return     * @throws Exception     */    public static String initMacKey() throws Exception {        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);

        SecretKey secretKey = keyGenerator.generateKey();        return encryptBASE64(secretKey.getEncoded());    }

    /**     * HMAC加密     *     * @param data     * @param key     * @return     * @throws Exception     */    public static byte[] encryptHMAC(byte[] data, String key) throws Exception {

        SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);        Mac mac = Mac.getInstance(secretKey.getAlgorithm());        mac.init(secretKey);

        return mac.doFinal(data);

    }}
package com.fj.blockchainmy.security;

import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;import java.security.*;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.HashMap;import java.util.Map;

/** * @author: yangchun * @description: * @date: Created in 2019-11-12 15:24 */public class RSACoder extends Coder{    public static final String KEY_ALGORITHM = "RSA";    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

    private static final String PUBLIC_KEY = "RSAPublicKey";    private static final String PRIVATE_KEY = "RSAPrivateKey";

    /**     * 用私钥对信息生成数字签名     *     * @param data     *            加密数据     * @param privateKey     *            私钥     *     * @return     * @throws Exception     */    public static String sign(byte[] data, String privateKey) throws Exception {        // 解密由base64编码的私钥        byte[] keyBytes = decryptBASE64(privateKey);

        // 构造PKCS8EncodedKeySpec对象        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);

        // KEY_ALGORITHM 指定的加密算法        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        // 取私钥匙对象        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);

        // 用私钥对信息生成数字签名        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);        signature.initSign(priKey);        signature.update(data);

        return encryptBASE64(signature.sign());    }

    /**     * 校验数字签名     *     * @param data     *            加密数据     * @param publicKey     *            公钥     * @param sign     *            数字签名     *     * @return 校验成功返回true 失败返回false     * @throws Exception     *     */    public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {

        // 解密由base64编码的公钥        byte[] keyBytes = decryptBASE64(publicKey);

        // 构造X509EncodedKeySpec对象        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);

        // KEY_ALGORITHM 指定的加密算法        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        // 取公钥匙对象        PublicKey pubKey = keyFactory.generatePublic(keySpec);

        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);        signature.initVerify(pubKey);        signature.update(data);

        // 验证签名是否正常        return signature.verify(decryptBASE64(sign));    }

    /**     * 解密<br>     * 用私钥解密     *     * @param data     * @param key     * @return     * @throws Exception     */    public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {        // 对密钥解密        byte[] keyBytes = decryptBASE64(key);

        // 取得私钥        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);

        // 对数据解密        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        return cipher.doFinal(data);    }

    /**     * 解密<br>     * 用公钥解密     *     * @param data     * @param key     * @return     * @throws Exception     */    public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception {        // 对密钥解密        byte[] keyBytes = decryptBASE64(key);

        // 取得公钥        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);        Key publicKey = keyFactory.generatePublic(x509KeySpec);

        // 对数据解密        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());        cipher.init(Cipher.DECRYPT_MODE, publicKey);

        return cipher.doFinal(data);    }

    /**     * 加密<br>     * 用公钥加密     *     * @param data     * @param key     * @return     * @throws Exception     */    public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception {        // 对公钥解密        byte[] keyBytes = decryptBASE64(key);

        // 取得公钥        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);        Key publicKey = keyFactory.generatePublic(x509KeySpec);

        // 对数据加密        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());        cipher.init(Cipher.ENCRYPT_MODE, publicKey);

        return cipher.doFinal(data);    }

    /**     * 加密<br>     * 用私钥加密     *     * @param data     * @param key     * @return     * @throws Exception     */    public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception {        // 对密钥解密        byte[] keyBytes = decryptBASE64(key);

        // 取得私钥        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);

        // 对数据加密        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());        cipher.init(Cipher.ENCRYPT_MODE, privateKey);

        return cipher.doFinal(data);    }

    /**     * 取得私钥     *     * @param keyMap     * @return     * @throws Exception     */    public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {        Key key = (Key) keyMap.get(PRIVATE_KEY);

        return encryptBASE64(key.getEncoded());    }

    /**     * 取得公钥     *     * @param keyMap     * @return     * @throws Exception     */    public static String getPublicKey(Map<String, Object> keyMap) throws Exception {        Key key = (Key) keyMap.get(PUBLIC_KEY);

        return encryptBASE64(key.getEncoded());    }

    /**     * 初始化密钥     *     * @return     * @throws Exception     */    public static Map<String, Object> initKey() throws Exception {        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);        keyPairGen.initialize(1024);

        KeyPair keyPair = keyPairGen.generateKeyPair();

        // 公钥        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

        // 私钥        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

        Map<String, Object> keyMap = new HashMap<String, Object>(2);

        keyMap.put(PUBLIC_KEY, publicKey);        keyMap.put(PRIVATE_KEY, privateKey);        return keyMap;    }}
package com.blockchain.security;

import java.security.MessageDigest;import java.util.UUID;

import org.eclipse.jetty.util.security.Credential.MD5;

/** * 加密工具类 *  * @author aaron.rao * */public class CryptoUtil {   private CryptoUtil() {   }

   public static String SHA256(String str) {      MessageDigest messageDigest;      String encodeStr = "";      try {         messageDigest = MessageDigest.getInstance("SHA-256");         messageDigest.update(str.getBytes("UTF-8"));         encodeStr = byte2Hex(messageDigest.digest());      } catch (Exception e) {         System.out.println("getSHA256 is error" + e.getMessage());      }      return encodeStr;   }

   public static String MD5(String str) {      String resultStr = MD5.digest(str);      return resultStr.substring(4, resultStr.length());   }

   public static String UUID() {      return UUID.randomUUID().toString().replaceAll("\\-", "");   }

   private static String byte2Hex(byte[] bytes) {      StringBuilder builder = new StringBuilder();      String temp;      for (int i = 0; i < bytes.length; i++) {         temp = Integer.toHexString(bytes[i] & 0xFF);         if (temp.length() == 1) {            builder.append("0");         }         builder.append(temp);      }      return builder.toString();   }

}

原文地址:https://www.cnblogs.com/xiaofeiyang/p/11842509.html

时间: 2024-08-29 01:43:07

手写区块链(二):区块链开发中的密码学知识的相关文章

活到老学到老:iOS开发中的基础知识(一)

本文参考 标哥的博客:宝库iOS开发笔试题 进行学习整理.与其说是看面试题,不如说是对自己知识的巩固.工欲善其事必先利其器,基础知识不牢固可能会导致编程中的一些注意不到的问题.总之一句话:活到老,学到老. 1.数组中的元素去重问题. //重复元素 NSArray *array = [NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"5",@"1"

opencv 手写选择题阅卷 (二)字符识别

选择题基本上只需要识别ABCD和空五个内容,理论上应该识别率比较高的,识别代码参考了网上搜索的代码,因为参考的网址比较多,现在也弄不清是参考何处的代码了,在这里就不一一感谢了. 基本步骤: 一,识别函数接受一般64X64的灰度图像; 二,二值化并反色为黑底白字; 三,找出字符的最小包围矩形,并大小归一化为32X32; 四,计算图像的HOG特征; 五,用SVM分类器对HOG特征进行识别,从而确定当前图像属于ABCD还是空白; 整个识别代码还是比较简单的.这得得益于opencv 对分类器的封装,除了

大数据学习之手写MR框架(WordCount程序开发)08

简介:这里先手写一个MR程序,大致实现一个单词计数程序.帮助后面学习MapReduce组件. 1:先自定义一个Mapper接口 package it.dawn.HDFSPra.HandWritingMR; /** * @author Dawn * @date 2019年4月30日23:28:00 * @version 1.0 * * 思路? * 接口设计 */ public interface Mapper { //通用方法 public void map(String line,Context

(五十二)android开发中一些重要的参考网址

1.动画效果实现参考的网址 泡在网上的日子:http://www.jcodecraeer.com/plus/list.php?tid=31&codecategory=500 (不同的动画效果,分类很好,便于搜索) github:https://github.com/Trinea/android-open-project(动画效果网址) https://github.com/FX-Max/Point-of-Android (一些知识点的总结网址) 属性动画讲解的不错的网址:http://www.c

雷观(二十二):项目开发中,要少做无用功

最近,正在重构一个项目的后台管理系统. 注意到,所有的table列表页,都有个搜索功能.后端的搜索功能,还是需要一点代码去实现.然后,还得去测试一遍. 但是呢,忽然意识到,有的页面根本没有必要增加"搜索"功能. 比如,有个表,实际项目中是"借款人"这个user表.真实环境下,尤其是项目早期过程中,根本不可能有多少"数据"或者说"借款人用户".一页,显示20个,基本上就足够了. 这个时候,增加"搜索"功能这种

Web开发中的网络知识(应用层)

一.网络分层 二.应用层协议--HTTP.DNS和SSH 2.1 http协议 1. 定义:超文本传输协议( Hyper Text Transfer Protocol ),是用于传输诸如HTML的超媒体文档的应用层协议.它被设计用于Web浏览器和Web服务器之间的通信,但也可以用于其它目的. HTTP遵循经典的客户端-服务端模型,客户端打开一个连接以发出请求,然后等待收到服务器端的响应. HTTP是无状态协议,意味着服务器不会在两个请求之间保留任何数据(状态).虽然通常基于TCP / IP层,但

区块链币币交易系统开发是未来的发展趋势

与传统技术对比,区块链币币交易系统开发具有以下四个方面的优势: 一是难以篡改,更加安全.在传统信息系统的安全方案中,安全依赖于层层设防的访问控制.通过区块链币币交易系统开发技术,记录交易的数据库任何人都可以访问,但由于巧妙的设计并辅以密码学和共识机制,区块链币币交易系统开发的数据记录方式使得修改某一数据需要变更所有的后续数据记录,难度极大.实践证明,这样一个数据库可以确保市值达千亿美金数字货币,在全球黑K的***下,运转稳定. 二是异构多活,可靠性强.区块链币币交易系统开发每个系统参与方都是一个

C#中调用Matlab人工神经网络算法实现手写数字识别

手写数字识别实现 设计技术参数:通过由数字构成的图像,自动实现几个不同数字的识别,设计识别方法,有较高的识别率 关键字:二值化  投影  矩阵  目标定位  Matlab 手写数字图像识别简介: 手写阿拉伯数字识别是图像内容识别中较为简单的一个应用领域,原因有被识别的模式数较少(只有0到9,10个阿拉伯数字).阿拉伯数字笔画少并且简单等.手写阿拉伯数字的识别采用的方法相对于人脸识别.汉字识别等应用领域来说可以采用更为灵活的方法,例如基于规则的方法.基于有限状态自动机的方法.基于统计的方法和基于神

我是这样手写Spring的,麻雀虽小,五脏俱全

人见人爱的Spring已然不仅仅只是一个框架了.如今,Spring已然成为了一个生态.但深入了解Spring的却寥寥无几.这里,我带大家一起来看看,我是如何手写Spring的.我将结合对Spring十多年的研究经验,用不到400行代码来描述Spring IOC.DI.MVC的精华设计思想,并保证基本功能完整.首先,我们先来介绍一下Spring的三个阶段,配置阶段.初始化阶段和运行阶段(如图):配置阶段:主要是完成application.xml配置和Annotation配置.初始化阶段:主要是加载