本文主要是介绍网络加密解密原理(三) RSA加密解密及数字签名Java实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
流程分析:- 甲方构建密钥对儿,将公钥公布给乙方,将私钥保留。
- 甲方使用私钥加密数据,然后用私钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用公钥、签名来验证待解密数据是否有效,如果有效使用公钥对数据解密。
- 乙方使用公钥加密数据,向甲方发送经过加密后的数据;甲方获得加密数据,通过私钥解密。
按如上步骤给出序列图,如下:
通过java代码实现如下:Coder类见 Java加密技术(一)
- import
java.security.Key; - import
java.security.KeyFactory; - import
java.security.KeyPair; - import
java.security.KeyPairGenerator; - import
java.security.PrivateKey; - import
java.security.PublicKey; - import
java.security.Signature; - 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; -
- import
javax.crypto.Cipher; -
-
- public
abstract 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"; -
-
-
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()); -
} -
-
-
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)); -
} -
-
-
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); -
} -
-
-
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); -
} -
-
-
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); -
} -
-
-
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); -
} -
-
-
public static String getPrivateKey(Map<String, Object> keyMap) -
throws Exception { -
Key key = (Key) keyMap.get(PRIVATE_KEY); -
-
return encryptBASE64(key.getEncoded()); -
} -
-
-
public static String getPublicKey(Map<String, Object> keyMap) -
throws Exception { -
Key key = (Key) keyMap.get(PUBLIC_KEY); -
-
return encryptBASE64(key.getEncoded()); -
} -
-
-
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; -
} - }
再给出一个测试类:
- import
static org.junit.Assert.*; -
- import
org.junit.Before; - import
org.junit.Test; -
- import
java.util.Map; -
-
- public
class RSACoderTest { -
private String publicKey; -
private String privateKey; -
-
@Before -
public void setUp() throws Exception { -
Map<String, Object> keyMap = RSACoder.initKey(); -
-
publicKey = RSACoder.getPublicKey(keyMap); -
privateKey = RSACoder.getPrivateKey(keyMap); -
System.err.println("公钥: nr" + publicKey); -
System.err.println("私钥: nr" + privateKey); -
} -
-
@Test -
public void test() throws Exception { -
System.err.println("公钥加密——私钥解密"); -
String inputStr = "abc"; -
byte[] data = inputStr.getBytes(); -
-
byte[] encodedData = RSACoder.encryptByPublicKey(data, publicKey); -
-
byte[] decodedData = RSACoder.decryptByPrivateKey(encodedData, -
privateKey); -
-
String outputStr = new String(decodedData); -
System.err.println("加密前: " + inputStr + "nr" + "解密后: " + outputStr); -
assertEquals(inputStr, outputStr); -
-
} -
-
@Test -
public void testSign() throws Exception { -
System.err.println("私钥加密——公钥解密"); -
String inputStr = "sign"; -
byte[] data = inputStr.getBytes(); -
-
byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey); -
-
byte[] decodedData = RSACoder -
.decryptByPublicKey(encodedData, publicKey); -
-
String outputStr = new String(decodedData); -
System.err.println("加密前: " + inputStr + "nr" + "解密后: " + outputStr); -
assertEquals(inputStr, outputStr); -
-
System.err.println("私钥签名——公钥验证签名"); -
// 产生签名 -
String sign = RSACoder.sign(encodedData, privateKey); -
System.err.println("签名:r" + sign); -
-
// 验证签名 -
boolean status = RSACoder.verify(encodedData, publicKey, sign); -
System.err.println("状态:r" + status); -
assertTrue(status); -
-
} -
- }
控制台输出:
- 公钥:
-
- MIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQCYU/+I0+z1aBl5X6DUUOHQ7FZpmBSDbK Ttx89J - EcB64jFCkunELT8qiKly7fzE
qD03g8ALlu5XvX+bBqHFy7YPJJP0ekE2X3wjUnh 2NxlqpH3/B/xm - 1ZdSlCwDIkbijhBVDjA/bu5BObhZqQmDwIxlQInL9oVz
+o6FbAZCyHBd7wIDAQAB -
- 私钥:
-
- MIICdgIBADANBgkqhkiG9w0B
AQEFAASCAmAwggJcAgEAAoGB AJhT/4jT7PVoGXlfoNRQ4dDsVmmY - FINspO3Hz0kRwHriMUKS6cQt
PyqIqXLt/MSoPTeDwAuW7le9f5sGocXLt g8kk/R6QTZffCNSeHY3 - GWqkff8H/GbVl1KULAMiRuKOEFUOMD9u7
kE5uFmpCYPAjGVAicv2hXP6j oVsBkLIcF3vAgMBAAEC - gYBvZHWoZHmS2EZQqKqeuGr5
8eobG9hcZzWQoJ4nq/CarBAjw/VovUHE490uK3S9ht4FW7Yzg3 LV - /MB06Huifh6qf/X9NQA7SeZRRC8gnCQk6JuDIE
VJOud5jU+9tyumJakDKodQ3Jf2zQtNr+5ZdEPl - uwWgv9c4kmpjhAdyMuQmYQJB
ANn6pcgvyYaia52dnu+yBUsGkaFfwXkzFSExIbi0MXT khEb/ER/D - rLytukkUu5S5ecz/KBa8U4xIslZDYQbLz5ECQQCy
5dutt7RsxN4+dxCWn0/1FrkWl2G329Ucewm3 - QU9CKu4D+7Kqdj+Ha3lXP8F0Etaaapi7+EfkRUpukn2ItZV/AkEAlk+I0iphxT1rCB0Q5CjWDY5S
- Df2B5JmdEG5Y2o0nLXwG2w44
OLct/k2uD4cEcuITY5Dvi/4BftMCZwm/dnhEgQJACIktJSnJwxLV - o9dchENPtlsCM9C/Sd2EWpqISSUlmfugZbJBwR5p
Q5XeMUqKeXZYpP+HEBj1nS+tMH9u2/IGEwJA - fL8mZiZXan/oBKrblAbplNcKWGRVD/3y65042PAEeghahlJMiYquV5
DzZajuuT0wbJ5xQuZB01+X - nfpFpBJ2dw==
-
- 公钥加密——私钥解密
- 加密前:
abc -
- 解密后:
abc - 公钥:
-
- MIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQDdOj40yEB4 8XqWxmPILmJAc7UecIN7F32e tSHF - 9rwbuEh3+iTPOGSxhoSQpOED0vOb0ZIMk
BXZSgsxLaBSin2RZ09YKWRjt pCA0kDkiD11gj4tzTiM - l9qq1kwSK7ZkGAgodEn3yIIL
VmQDuEImHOXFtulvJ71ka07u 3LuwUNdB/wIDAQAB -
- 私钥:
-
- MIICdwIBADANBgkqhkiG9w0B
AQEFAASCAmEwggJdAgEAAoGB AN06PjTIQHjxepbGY8guYkBz tR5w - g3sXfZ61IcX2vBu4SHf6JM84
ZLGGhJCk4QPS85vRkgyQFdlK CzEtoFKKfZFnT1gpZGO2kIDS QOSI - PXWCPi3NOIyX2qrWTBIrtmQY
CCh0SffIggtWZAO4QiYc5cW2 6W8nvWRrTu7cu7BQ10H/AgMBAAEC - gYEAz2JWBizjI31bqhP4XiP9
PuY5F3vqBW4T+L9cFbQiyumKJc58yzTWUAUGK IIn3enXLG7dNqGr - mbJro4JeFIJ3CiVDpXR9+FluIgI4SXm7ioGKF2NOMA9LR
5Fu82W+pLfpTN2y2SaLYWEDZyp53BxY - j9gUxaxi1MQs+C1ZgDF2xmECQQDy70bQntbRf
ysP+ppCtd56YRnES1Tyekw0wryS2 tr+ivQJl7JF - gp5rPAOXpgrq36xHDwUspQ0s
J0vj0O7ywxr1AkEA6SAaLhrJ JrYucC0jxwAhUYyaPN+aOsWymaRh - 9jA/Wc0wp29SbGTh5CcMuGpXm1g0
M+FKW3dGiHgS3rVUKim4owJAbn xgapUzAgiiHxxMeDaavnHW - 9C2GrtjsO7qtZOTgYI/1uT8itvZW8lJTF+9OW8/qXE76fXl7ai9dFnl5kzMk2QJ
BALfHz/vCsArt - mkRiwY6zApE4Z6tPl1V33ymS
VovvUzHnOdD1SKQdD5t+UV/crb3QVi8ED0t2B0u0ZSPfDT/D7kMC - QDpwdj9k2F5aokLHBHUNJPFD
Ap7a5QMaT64gv/d48ITJ68Co+v5WzLMpzJBYXK6PAtqIhxbuP Ec2 - I2k1Afmrwyw=
-
- 私钥加密——公钥解密
- 加密前:
sign -
- 解密后:
sign - 私钥签名——公钥验证签名
- 签名:
- ud1RsIwmSC1pN22I4IXteg1V
D2FbiehKUfNxgVSHzvQNIK+d20FCkHCqh9djP3h94iWnIUY 0ifU+ - mbJkhAl/i5krExOE0hknOnPMcEP+lZV1RbJI2zG2YooSp2XDleqr
Qk5e/QF2Mx0Zxt8Xsg7ucVpn - i3wwbYWs9wSzIf0UjlM=
-
- 状态:
- true
类似数字签名,数字信封是这样描述的:
数字信封
数字信封用加密技术来保证只有特定的收信人才能阅读信的内容。
流程:
转:http://security.group.iteye.com/group/wiki/2280-non-symmetric-encryption-Digital-signature
这篇关于网络加密解密原理(三) RSA加密解密及数字签名Java实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!