生活随笔
收集整理的這篇文章主要介紹了
非对称加密算法RSA--转
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
RSA?
??? 這種算法1978年就出現(xiàn)了,它是第一個(gè)既能用于數(shù)據(jù)加密也能用于數(shù)字簽名的算法。它易于理解和操作,也很流行。算法的名字以發(fā)明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman。?
??? 這種加密算法的特點(diǎn)主要是密鑰的變化,上文我們看到DES只有一個(gè)密鑰。相當(dāng)于只有一把鑰匙,如果這把鑰匙丟了,數(shù)據(jù)也就不安全了。RSA同時(shí)有兩把鑰匙,公鑰與私鑰。同時(shí)支持?jǐn)?shù)字簽名。數(shù)字簽名的意義在于,對(duì)傳輸過(guò)來(lái)的數(shù)據(jù)進(jìn)行校驗(yàn)。確保數(shù)據(jù)在傳輸工程中不被修改。?
流程分析:?
甲方構(gòu)建密鑰對(duì)兒,將公鑰公布給乙方,將私鑰保留。甲方使用私鑰加密數(shù)據(jù),然后用私鑰對(duì)加密后的數(shù)據(jù)簽名,發(fā)送給乙方簽名以及加密后的數(shù)據(jù);乙方使用公鑰、簽名來(lái)驗(yàn)證待解密數(shù)據(jù)是否有效,如果有效使用公鑰對(duì)數(shù)據(jù)解密。乙方使用公鑰加密數(shù)據(jù),向甲方發(fā)送經(jīng)過(guò)加密后的數(shù)據(jù);甲方獲得加密數(shù)據(jù),通過(guò)私鑰解密。
按如上步驟給出序列圖,如下:?
通過(guò)java代碼實(shí)現(xiàn)如下:Coder類見(jiàn)?Java加密技術(shù)(一)?
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;/*** RSA安全編碼組件* * @author 梁棟* @version 1.0* @since 1.0*/
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"
;/*** 用私鑰對(duì)信息生成數(shù)字簽名* * @param data* 加密數(shù)據(jù)* @param privateKey* 私鑰* * @return* @throws Exception*/public static String sign(
byte[] data, String privateKey)
throws Exception {// 解密由base64編碼的私鑰byte[] keyBytes =
decryptBASE64(privateKey);// 構(gòu)造PKCS8EncodedKeySpec對(duì)象PKCS8EncodedKeySpec pkcs8KeySpec =
new PKCS8EncodedKeySpec(keyBytes);// KEY_ALGORITHM 指定的加密算法KeyFactory keyFactory =
KeyFactory.getInstance(KEY_ALGORITHM);// 取私鑰匙對(duì)象PrivateKey priKey =
keyFactory.generatePrivate(pkcs8KeySpec);// 用私鑰對(duì)信息生成數(shù)字簽名Signature signature =
Signature.getInstance(SIGNATURE_ALGORITHM);signature.initSign(priKey);signature.update(data);return encryptBASE64(signature.sign());}/*** 校驗(yàn)數(shù)字簽名* * @param data* 加密數(shù)據(jù)* @param publicKey* 公鑰* @param sign* 數(shù)字簽名* * @return 校驗(yàn)成功返回true 失敗返回false* @throws Exception* */public static boolean verify(
byte[] data, String publicKey, String sign)throws Exception {// 解密由base64編碼的公鑰byte[] keyBytes =
decryptBASE64(publicKey);// 構(gòu)造X509EncodedKeySpec對(duì)象X509EncodedKeySpec keySpec =
new X509EncodedKeySpec(keyBytes);// KEY_ALGORITHM 指定的加密算法KeyFactory keyFactory =
KeyFactory.getInstance(KEY_ALGORITHM);// 取公鑰匙對(duì)象PublicKey pubKey =
keyFactory.generatePublic(keySpec);Signature signature =
Signature.getInstance(SIGNATURE_ALGORITHM);signature.initVerify(pubKey);signature.update(data);// 驗(yàn)證簽名是否正常return signature.verify(decryptBASE64(sign));}/*** 解密<br>* 用私鑰解密* * @param data* @param key* @return* @throws Exception*/public static byte[] decryptByPrivateKey(
byte[] data, String key)throws Exception {// 對(duì)密鑰解密byte[] keyBytes =
decryptBASE64(key);// 取得私鑰PKCS8EncodedKeySpec pkcs8KeySpec =
new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory =
KeyFactory.getInstance(KEY_ALGORITHM);Key privateKey =
keyFactory.generatePrivate(pkcs8KeySpec);// 對(duì)數(shù)據(jù)解密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 {// 對(duì)密鑰解密byte[] keyBytes =
decryptBASE64(key);// 取得公鑰X509EncodedKeySpec x509KeySpec =
new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory =
KeyFactory.getInstance(KEY_ALGORITHM);Key publicKey =
keyFactory.generatePublic(x509KeySpec);// 對(duì)數(shù)據(jù)解密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 {// 對(duì)公鑰解密byte[] keyBytes =
decryptBASE64(key);// 取得公鑰X509EncodedKeySpec x509KeySpec =
new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory =
KeyFactory.getInstance(KEY_ALGORITHM);Key publicKey =
keyFactory.generatePublic(x509KeySpec);// 對(duì)數(shù)據(jù)加密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 {// 對(duì)密鑰解密byte[] keyBytes =
decryptBASE64(key);// 取得私鑰PKCS8EncodedKeySpec pkcs8KeySpec =
new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory =
KeyFactory.getInstance(KEY_ALGORITHM);Key privateKey =
keyFactory.generatePrivate(pkcs8KeySpec);// 對(duì)數(shù)據(jù)加密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;}
} 再給出一個(gè)測(cè)試類:?
import static org.junit.Assert.*
;import org.junit.Before;
import org.junit.Test;import java.util.Map;/*** * @author 梁棟* @version 1.0* @since 1.0*/
public class RSACoderTest {private String publicKey;private String privateKey;@Beforepublic void setUp()
throws Exception {Map<String, Object> keyMap =
RSACoder.initKey();publicKey =
RSACoder.getPublicKey(keyMap);privateKey =
RSACoder.getPrivateKey(keyMap);System.err.println("公鑰: \n\r" +
publicKey);System.err.println("私鑰: \n\r" +
privateKey);}@Testpublic 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 + "\n\r" + "解密后: " +
outputStr);assertEquals(inputStr, outputStr);}@Testpublic 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 + "\n\r" + "解密后: " +
outputStr);assertEquals(inputStr, outputStr);System.err.println("私鑰簽名——公鑰驗(yàn)證簽名"
);// 產(chǎn)生簽名String sign =
RSACoder.sign(encodedData, privateKey);System.err.println("簽名:\r" +
sign);// 驗(yàn)證簽名boolean status =
RSACoder.verify(encodedData, publicKey, sign);System.err.println("狀態(tài):\r" +
status);assertTrue(status);}} ?
原文地址:http://snowolf.iteye.com/blog/381767
?
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/p/3925444.html
總結(jié)
以上是生活随笔為你收集整理的非对称加密算法RSA--转的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。