对称加密的加密密钥和解密解密密钥一致,即加密和解密用同一个密钥。
非对称加密有两个密钥,一个公钥一个私钥,两者成对出现。两者不一样,遵循“公钥加密私钥解密”和“私钥加密公钥解密”的原则。
RSA是常用的非对称加密算法。
- RSA算法
模型如下
算法实现
/**
* 初始化RSA密钥对
* @return
*/
public static String[] initRSAKey(){
try {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
return new String[]{Hex.encodeHexString(publicKey.getEncoded()), Hex.encodeHexString(privateKey.getEncoded())};
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
/**
* RSA私钥加解密
* @param data
* @param key
* @param mode
* 0-加密,1-解密
* @return
*/
public static String RSAByPrivateKey(String data, String key, int mode){
try {
//取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Hex.decodeHex(key.toCharArray()));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
if (mode == 0) {
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
} else {
cipher.init(Cipher.DECRYPT_MODE, privateKey);
}
return Hex.encodeHexString(cipher.doFinal(Hex.decodeHex(data
.toCharArray())));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (DecoderException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return null;
}
/**
* RSA公钥加解密
* @param data
* @param key
* @param mode
* 0-加密,1-解密
* @return
*/
public static String RSAByPublicKey(String data, String key, int mode){
try {
//取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Hex.decodeHex(key.toCharArray()));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key publicKey = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
if (mode == 0) {
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
} else {
cipher.init(Cipher.DECRYPT_MODE, publicKey);
}
return Hex.encodeHexString(cipher.doFinal(Hex.decodeHex(data
.toCharArray())));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (DecoderException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return null;
}
测试代码
String[] key = initRSAKey();
String publicKey = key[0];
System.out.println("RSA公钥:"+publicKey);
String privateKey = key[1];
System.out.println("RSA私钥:"+privateKey);
String data = "404142434445464748494a4b4c4d4e4f";
System.out.println("原始数据:"+data);
String encode = RSAByPrivateKey(data, privateKey, 0);
System.out.println("RSA私钥加密后:"+encode);
String decode = RSAByPublicKey(encode, publicKey, 1);
System.out.println("RSA公钥解密后:"+decode);
encode = RSAByPublicKey(data, publicKey, 0);
System.out.println("RSA公钥加密后:"+encode);
decode = RSAByPrivateKey(encode, privateKey, 1);
System.out.println("RSA私钥解密后:"+decode);
运行结果
RSA公钥:30819f300d06092a864886f70d010101050003818d003081890281810085eda17a68c0091a04e3bc0337a2c627898b310425291bbfbb88f81839e6a318230d20da402298716d64ffb962edb3adaa3abacb8110c1073f96a3213a8f2ba33f8426b77b77a8f7940fd148398c63777a800f6fcf571dfbe22d49450b1b7d059c63af7453a176c7720328f03b78d914189c5ef13860119223caf9cc56baa0350203010001
RSA私钥:30820278020100300d06092a864886f70d0101010500048202623082025e0201000281810085eda17a68c0091a04e3bc0337a2c627898b310425291bbfbb88f81839e6a318230d20da402298716d64ffb962edb3adaa3abacb8110c1073f96a3213a8f2ba33f8426b77b77a8f7940fd148398c63777a800f6fcf571dfbe22d49450b1b7d059c63af7453a176c7720328f03b78d914189c5ef13860119223caf9cc56baa0350203010001028180695c012dd05c4a8cba8e01e9b20a0ec329d46392343dbbc3c11fc6b5204fcdbc7e4ea4aaadcbc98b6a190b8867484292fb994a3c3063e2c6f60266810c957728c95659f2234c37a56da17df9ad3bc8288d74845f3d49fd4a47efeafba45fd7675d10d084ad6f62d27799c82717f4862f355c98fd8f3c0cf9101404fef8a7db61024100c3acfa3cb22fd8655c683d7bd3834df8ecb8c5d6f451e63f4b587d26cb1605c0965c0ed5b0cb1bd207058d48297fe60b9b34b99578475a291909567e7e892c69024100af3773765608472d0a9e77c3587cd70224aa8109684f1fdf2977c1a8862f4910d5c90932b1a758c7935176eda130d5801baad5ef14fb4ba93aad46471bb40bed024100974e062130d77648ca6f803b638e40989ed33187c95c1ae20e6cda3949083a6274e1b246e271eb8d3808befa71bc8831a94dd7c310427c21134ef926cec95b21024100a2a5438dce70a2b961c915fd044fe639fc1535f0a89e0244e2366352ef34478bd417686d6151a96ca10896f02097b727d306f2cd9ad9663371df54843f6813450241008116aa820988c75f27abbada3547940543e90355763fcea8e3e1766713e46a575443f583a3b4dd4b67f55ed1a73f7db8541145cc5e68a296bd34863f61d5a994
原始数据:404142434445464748494a4b4c4d4e4f
RSA私钥加密后:433cdc548920a9ba300c938ba56c5eb17bcb52d7a8e7d5c967af7a98ac515447a15ec63cb01b91b4d03e8d53146c43181b0ee022b9423bd6e56c7483f8e34572fe0df519475bfda4453824526e1bfd3e6f9dadebd19acec1549024aa8ccc51246ca4c1ccbf6be1f16b88f4cb531a5ecba1d175d9ccc787fb2c348ab4dcdb4229
RSA公钥解密后:404142434445464748494a4b4c4d4e4f
RSA公钥加密后:3088bba16875fbd32a3e2136c2900b339ccb107bb5621b563c28eb5440975ae382befe3e91efee90184e6ef1e4791aeb811c9d36720606fbc7c778b15a22bfafcc30204ca7535e3563a07e695e87641b0dd0864978b4c81d6268718fd65d059c4085253223a7f38b2a7ce401c8802a697d9070a3b9df4552bc51904ee4a44942
RSA私钥解密后:404142434445464748494a4b4c4d4e4f