Java中数据传输加密与签名那些事( 二 )

 
非对称加密:市场上用的比较多的通常为RSA加密,RSA加密的流程与对称加密不同,相对于更加安全,通过生成两把秘钥(私钥/公钥),公钥通常用来对传输过程中的数据进行加密,私钥则用来对加密数据进行解密,公钥加密的内容只能对应的私钥才能解密,私钥加密的内容只能由对应的公钥解密,通常客户端存储公钥、服务端则存储私钥,这样,即使公钥被泄漏也没法破解密文信息;

Java中数据传输加密与签名那些事

文章插图
 
 
缺点:相对对称加密性能方面要慢很多,非敏感信息不建议使用;
RSA案例:
public class RSAUtils {protected static final Log log = LogFactory.getLog(RSAUtils.class);private static String KEY_RSA_TYPE = "RSA";private static int KEY_SIZE = 1024;//JDK方式RSA加密最大只有1024位private static int ENCODE_PART_SIZE = KEY_SIZE/8;public static final String PUBLIC_KEY_NAME = "public";public static final String PRIVATE_KEY_NAME = "private";public static void main(String[] args) {Map<String,String> map=RSAUtils.createRSAKeys(); //创建公私钥String str="Java资料社区";String enStr=encode(str,map.get("public"));//公钥加密System.out.println("加密后:"+enStr);String deStr=decode(enStr,map.get("private"));System.out.println("解密后:"+deStr);}/*** 创建公钥秘钥* @return*/public static Map<String,String> createRSAKeys(){Map<String,String> keyPairMap = new HashMap<>();//里面存放公私秘钥的Base64位加密try {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_RSA_TYPE);keyPairGenerator.initialize(KEY_SIZE,new SecureRandom());KeyPair keyPair = keyPairGenerator.generateKeyPair();//获取公钥秘钥String publicKeyValue = https://www.isolves.com/it/cxkf/yy/JAVA/2020-03-10/Base64.encodeBase64String(keyPair.getPublic().getEncoded());String privateKeyValue = Base64.encodeBase64String(keyPair.getPrivate().getEncoded());//存入公钥秘钥,以便以后获取keyPairMap.put(PUBLIC_KEY_NAME,publicKeyValue);keyPairMap.put(PRIVATE_KEY_NAME,privateKeyValue);} catch (NoSuchAlgorithmException e) {log.error("当前JDK版本没找到RSA加密算法!");e.printStackTrace();}return keyPairMap;}/*** 公钥加密* 描述:*1字节 = 8位;*最大加密长度如 1024位私钥时,最大加密长度为 128-11 = 117字节,不管多长数据,加密出来都是 128 字节长度 。* @param sourceStr* @param publicKeyBase64Str* @return*/public static String encode(String sourceStr,String publicKeyBase64Str){byte [] publicBytes = Base64.decodeBase64(publicKeyBase64Str);//公钥加密X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicBytes);List alreadyEncodeListData = new LinkedList<>();int maxEncodeSize = ENCODE_PART_SIZE - 11;String encodeBase64Result = null;try {KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA_TYPE);PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);Cipher cipher = Cipher.getInstance(KEY_RSA_TYPE);cipher.init(Cipher.ENCRYPT_MODE,publicKey);byte[] sourceBytes = sourceStr.getBytes("utf-8");int sourceLen = sourceBytes.length;for(int i=0;i maxEncodeSize){tempLen = maxEncodeSize;}byte[] tempBytes = new byte[tempLen];//待加密分段数据System.arraycopy(sourceBytes,i,tempBytes,0,tempLen);byte[] tempAlreadyEncodeData = cipher.doFinal(tempBytes);alreadyEncodeListData.add(tempAlreadyEncodeData);}int partLen = alreadyEncodeListData.size();//加密次数int allEncodeLen = partLen * ENCODE_PART_SIZE;byte[] encodeData = new byte[allEncodeLen];//存放所有RSA分段加密数据for (int i = 0; i < partLen; i++) {byte[] tempByteList = alreadyEncodeListData.get(i);System.arraycopy(tempByteList,0,encodeData,i*ENCODE_PART_SIZE,ENCODE_PART_SIZE);}encodeBase64Result = Base64.encodeBase64String(encodeData);} catch (Exception e) {e.printStackTrace();}return encodeBase64Result;}/*** 私钥解密* @param sourceBase64RSA* @param privateKeyBase64Str*/public static String decode(String sourceBase64RSA,String privateKeyBase64Str){byte[] privateBytes = Base64.decodeBase64(privateKeyBase64Str);byte[] encodeSource = Base64.decodeBase64(sourceBase64RSA);int encodePartLen = encodeSource.length/ENCODE_PART_SIZE;List decodeListData = new LinkedList<>();//所有解密数据String decodeStrResult = null;//私钥解密PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateBytes);try {KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA_TYPE);PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);Cipher cipher = Cipher.getInstance(KEY_RSA_TYPE);cipher.init(Cipher.DECRYPT_MODE,privateKey);int allDecodeByteLen = 0;//初始化所有被解密数据长度for (int i = 0; i < encodePartLen; i++) {byte[] tempEncodedData = new byte[ENCODE_PART_SIZE];System.arraycopy(encodeSource,i*ENCODE_PART_SIZE,tempEncodedData,0,ENCODE_PART_SIZE);byte[] decodePartData = cipher.doFinal(tempEncodedData);decodeListData.add(decodePartData);allDecodeByteLen += decodePartData.length;}byte [] decodeResultBytes = new byte[allDecodeByteLen];for (int i = 0,curPosition = 0; i


推荐阅读