生活随笔
收集整理的這篇文章主要介紹了
数据安全管理:RSA加密算法,签名验签流程详解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本文源碼:GitHub·點這里 || GitEE·點這里
一、RSA算法簡介
1、加密解密
RSA加密是一種非對稱加密,在公開密鑰加密和電子商業中RSA被廣泛使用。可以在不直接傳遞密鑰的情況下,完成加解密操作。這能夠確保信息的安全性,避免了直接傳遞密鑰所造成的被破解的風險。是由一對密鑰來進行加解密的過程,分別稱為公鑰和私鑰。該加密算法的原理就是對一極大整數做因數分解的困難性來保證安全性。
2、簽名驗簽
數字簽名就是信息的來源添加一段無法被偽造的加密字符串,這段數字串作為對信息的來源真實性的一個有效證明。這個過程稱為簽名和驗簽。
二、場景描述
- 消息發送方:甲方,持有公鑰
- 消息接收方:乙方,持有私鑰
1、加密解密過程
(1)、乙方生成一對密鑰即公鑰和私鑰,私鑰不公開,乙方自己持有,公鑰為公開,甲方持有。
(2)、乙方收到甲方加密的消息,使用私鑰對消息進行解密,獲取明文。
2、簽名驗簽過程
(1)、乙方收到消息后,需要回復甲方,用私鑰對回復消息簽名,并將消息明文和消息簽名回復甲方。
(2)、甲方收到消息后,使用公鑰進行驗簽,如果驗簽結果是正確的,則證明消息是乙方回復的。
三、源代碼實現
1、密鑰字符串獲取
private static HashMap
<String, String> getTheKeys() {HashMap
<String, String> keyPairMap
= new HashMap<String, String>();KeyPairGenerator keyPairGen
= null
;try {keyPairGen
= KeyPairGenerator
.getInstance("RSA");} catch (NoSuchAlgorithmException e
) {e
.printStackTrace();}keyPairGen
.initialize(1024);KeyPair keyPair
= keyPairGen
.generateKeyPair();String publicKey
= printBase64Binary(keyPair
.getPublic().getEncoded());String privateKey
= printBase64Binary(keyPair
.getPrivate().getEncoded());keyPairMap
.put("publicKey", publicKey
);keyPairMap
.put("privateKey", privateKey
);return keyPairMap
;
}
文件位置
public static final String PUB_KEY
= "rsaKey/public.key" ;
public static final String PRI_KEY
= "rsaKey/private.key" ;
文件加載
public static String getKey
(String keyPlace
) throws Exception
{BufferedReader br
= null
;try {br
= new BufferedReader(new InputStreamReader(RsaCryptUtil
.class.getClassLoader().getResourceAsStream(keyPlace
)));String readLine
= null
;StringBuilder keyValue
= new StringBuilder();while((readLine
= br
.readLine())!=null
){if(!(readLine
.charAt(0)=='-')){keyValue
.append(readLine
);}}return keyValue
.toString();} catch (Exception e
) {throw new Exception("RSA密鑰讀取錯誤",e
) ;} finally{if (br
!= null
) {try {br
.close();} catch (Exception e
) {System
.out
.println("密鑰讀取流關閉異常");}}}
}
2、公鑰和私鑰
public static RSAPublicKey
createPublicKey(String publicKeyValue
) throws Exception
{try {byte[] buffer
= DatatypeConverter
.parseBase64Binary(publicKeyValue
);KeyFactory keyFactory
= KeyFactory
.getInstance("RSA");X509EncodedKeySpec keySpec
= new X509EncodedKeySpec(buffer
);return (RSAPublicKey
) keyFactory
.generatePublic(keySpec
);} catch (Exception e
) {throw new Exception("公鑰創建失敗", e
);}
}
public static RSAPrivateKey
createPrivateKey(String privateKeyValue
) throws Exception
{try {byte[] buffer
= javax
.xml
.bind
.DatatypeConverter
.parseBase64Binary(privateKeyValue
);PKCS8EncodedKeySpec keySpec
= new PKCS8EncodedKeySpec(buffer
);KeyFactory keyFactory
= KeyFactory
.getInstance("RSA");return (RSAPrivateKey
) keyFactory
.generatePrivate(keySpec
);} catch (Exception e
) {throw new Exception("私鑰創建失敗", e
);}
}
3、加密和解密
public static String
encrypt(RSAPublicKey publicKey
, byte[] clearData
) throws Exception
{if (publicKey
== null
) {throw new Exception("加密公鑰為空, 無法加密");}try {Cipher cipher
= Cipher
.getInstance("RSA") ;cipher
.init(Cipher
.ENCRYPT_MODE
, publicKey
);byte[] output
= cipher
.doFinal(clearData
);return printBase64Binary(output
);} catch (Exception e
) {throw new Exception("公鑰加密失敗",e
);}
}
public static String
decrypt(RSAPrivateKey privateKey
, byte[] cipherData
) throws Exception
{if (privateKey
== null
) {throw new Exception("解密私鑰為空, 無法解密");}try {Cipher cipher
= Cipher
.getInstance("RSA") ;cipher
.init(Cipher
.DECRYPT_MODE
, privateKey
);byte[] output
= cipher
.doFinal(cipherData
);return new String(output
);} catch (BadPaddingException e
) {throw new Exception("私鑰解密失敗",e
);}
}
4、簽名和驗簽
public static String sign
(String signData
, PrivateKey privateKey
) throws Exception
{byte[] keyBytes
= privateKey
.getEncoded();PKCS8EncodedKeySpec keySpec
= new PKCS8EncodedKeySpec(keyBytes
);KeyFactory keyFactory
= KeyFactory
.getInstance("RSA");PrivateKey key
= keyFactory
.generatePrivate(keySpec
);Signature signature
= Signature
.getInstance("MD5withRSA");signature
.initSign(key
);signature
.update(signData
.getBytes());return printBase64Binary(signature
.sign());
}
public static boolean verify(String srcData
, PublicKey publicKey
, String sign
) throws Exception
{byte[] keyBytes
= publicKey
.getEncoded();X509EncodedKeySpec keySpec
= new X509EncodedKeySpec(keyBytes
);KeyFactory keyFactory
= KeyFactory
.getInstance("RSA");PublicKey key
= keyFactory
.generatePublic(keySpec
);Signature signature
= Signature
.getInstance("MD5withRSA");signature
.initVerify(key
);signature
.update(srcData
.getBytes());return signature
.verify(parseBase64Binary(sign
));
}
5、編碼和解碼
public static String
printBase64Binary(byte[] bytes
) {return DatatypeConverter
.printBase64Binary(bytes
);
}
public static byte[] parseBase64Binary(String value
) {return DatatypeConverter
.parseBase64Binary(value
);
}
6、測試代碼塊
public static void testCreateKey
() throws Exception
{HashMap
<String, String> map
= RsaCryptUtil
.getTheKeys();String privateKeyStr
=map
.get("privateKey");String publicKeyStr
=map
.get("publicKey");System
.out
.println("私鑰:"+privateKeyStr
);System
.out
.println("公鑰:"+publicKeyStr
);String originData
="cicada-smile";System
.out
.println("原文:"+originData
);String encryptData
= RsaCryptUtil
.encrypt(RsaCryptUtil
.createPublicKey(publicKeyStr
),originData
.getBytes());System
.out
.println("加密:"+encryptData
);String decryptData
=RsaCryptUtil
.decrypt(RsaCryptUtil
.createPrivateKey(privateKeyStr
),RsaCryptUtil
.parseBase64Binary(encryptData
));System
.out
.println("解密:"+decryptData
);
}
public static void testReadKey
() throws Exception
{String value
= getKey("rsaKey/public.key");System
.out
.println(value
);String privateKeyStr
= getKey(RsaCryptUtil
.PRI_KEY
) ;String publicKeyStr
= getKey(RsaCryptUtil
.PUB_KEY
) ;String originData
="cicada-smile";System
.out
.println("原文:"+originData
);String encryptData
= RsaCryptUtil
.encrypt(RsaCryptUtil
.createPublicKey(publicKeyStr
),originData
.getBytes());System
.out
.println("加密:"+encryptData
);String decryptData
=RsaCryptUtil
.decrypt(RsaCryptUtil
.createPrivateKey(privateKeyStr
),RsaCryptUtil
.parseBase64Binary(encryptData
));System
.out
.println("解密:"+decryptData
);
}
public static void testSignVerify
() throws Exception
{String signData
= "cicada-smile" ;String privateKeyStr
= getKey(RsaCryptUtil
.PRI_KEY
) ;String publicKeyStr
= getKey(RsaCryptUtil
.PUB_KEY
) ;String signValue
= sign(signData
,RsaCryptUtil
.createPrivateKey(privateKeyStr
)) ;boolean flag
= verify(signData
,RsaCryptUtil
.createPublicKey(publicKeyStr
),signValue
);System
.out
.println("原文:"+signData
);System
.out
.println("簽名:"+signValue
);System
.out
.println("驗簽:"+flag
);
}
四、源代碼地址
GitHub·地址
https://github.com/cicadasmile
GitEE·地址
https://gitee.com/cicadasmile
總結
以上是生活随笔為你收集整理的数据安全管理:RSA加密算法,签名验签流程详解的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。