-
介绍典型的非对称加密算法——RSA
2014-08-21 20:16:10接下来我们介绍典型的非对称加密算法——RSA RSA 这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, ...Java加密技术(四)——非对称加密算法RSA 博客分类: Java/Security
接下来我们介绍典型的非对称加密算法——RSA
RSA
这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman。
这种加密算法的特点主要是密钥的变化,上文我们看到DES只有一个密钥。相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输工程中不被修改。
流程分析:- 甲方构建密钥对儿,将公钥公布给乙方,将私钥保留。
- 甲方使用私钥加密数据,然后用私钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用公钥、签名来验证待解密数据是否有效,如果有效使用公钥对数据解密。
- 乙方使用公钥加密数据,向甲方发送经过加密后的数据;甲方获得加密数据,通过私钥解密。
按如上步骤给出序列图,如下:
通过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;
- /**
- * 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";
- /**
- * 用私钥对信息生成数字签名
- *
- * @param data
- * 加密数据
- * @param privateKey
- * 私钥
- *
- * @return
- * @throws Exception
- */
- 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());
- }
- /**
- * 校验数字签名
- *
- * @param data
- * 加密数据
- * @param publicKey
- * 公钥
- * @param sign
- * 数字签名
- *
- * @return 校验成功返回true 失败返回false
- * @throws Exception
- *
- */
- 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));
- }
- /**
- * 解密<br>
- * 用私钥解密
- *
- * @param data
- * @param key
- * @return
- * @throws Exception
- */
- 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);
- }
- /**
- * 解密<br>
- * 用公钥解密
- *
- * @param data
- * @param key
- * @return
- * @throws Exception
- */
- 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);
- }
- /**
- * 加密<br>
- * 用公钥加密
- *
- * @param data
- * @param key
- * @return
- * @throws Exception
- */
- 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);
- }
- /**
- * 加密<br>
- * 用私钥加密
- *
- * @param data
- * @param key
- * @return
- * @throws Exception
- */
- 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);
- }
- /**
- * 取得私钥
- *
- * @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;
- }
- }
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";/** * 用私钥对信息生成数字签名 * * @param data * 加密数据 * @param privateKey * 私钥 * * @return * @throws Exception */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());}/** * 校验数字签名 * * @param data * 加密数据 * @param publicKey * 公钥 * @param sign * 数字签名 * * @return 校验成功返回true 失败返回false * @throws Exception * */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));}/** * 解密<br> * 用私钥解密 * * @param data * @param key * @return * @throws Exception */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);}/** * 解密<br> * 用公钥解密 * * @param data * @param key * @return * @throws Exception */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);}/** * 加密<br> * 用公钥加密 * * @param data * @param key * @return * @throws Exception */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);}/** * 加密<br> * 用私钥加密 * * @param data * @param key * @return * @throws Exception */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);}/** * 取得私钥 * * @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;}}
再给出一个测试类:- 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;
- @Before
- public 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);
- }
- @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 + "\n\r" + "解密后: " + 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 + "\n\r" + "解密后: " + 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);
- }
- }
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("私钥签名——公钥验证签名");// 产生签名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);}}
控制台输出:- 公钥:
- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYU/+I0+z1aBl5X6DUUOHQ7FZpmBSDbKTtx89J
- EcB64jFCkunELT8qiKly7fzEqD03g8ALlu5XvX+bBqHFy7YPJJP0ekE2X3wjUnh2NxlqpH3/B/xm
- 1ZdSlCwDIkbijhBVDjA/bu5BObhZqQmDwIxlQInL9oVz+o6FbAZCyHBd7wIDAQAB
- 私钥:
- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJhT/4jT7PVoGXlfoNRQ4dDsVmmY
- FINspO3Hz0kRwHriMUKS6cQtPyqIqXLt/MSoPTeDwAuW7le9f5sGocXLtg8kk/R6QTZffCNSeHY3
- GWqkff8H/GbVl1KULAMiRuKOEFUOMD9u7kE5uFmpCYPAjGVAicv2hXP6joVsBkLIcF3vAgMBAAEC
- gYBvZHWoZHmS2EZQqKqeuGr58eobG9hcZzWQoJ4nq/CarBAjw/VovUHE490uK3S9ht4FW7Yzg3LV
- /MB06Huifh6qf/X9NQA7SeZRRC8gnCQk6JuDIEVJOud5jU+9tyumJakDKodQ3Jf2zQtNr+5ZdEPl
- uwWgv9c4kmpjhAdyMuQmYQJBANn6pcgvyYaia52dnu+yBUsGkaFfwXkzFSExIbi0MXTkhEb/ER/D
- rLytukkUu5S5ecz/KBa8U4xIslZDYQbLz5ECQQCy5dutt7RsxN4+dxCWn0/1FrkWl2G329Ucewm3
- QU9CKu4D+7Kqdj+Ha3lXP8F0Etaaapi7+EfkRUpukn2ItZV/AkEAlk+I0iphxT1rCB0Q5CjWDY5S
- Df2B5JmdEG5Y2o0nLXwG2w44OLct/k2uD4cEcuITY5Dvi/4BftMCZwm/dnhEgQJACIktJSnJwxLV
- o9dchENPtlsCM9C/Sd2EWpqISSUlmfugZbJBwR5pQ5XeMUqKeXZYpP+HEBj1nS+tMH9u2/IGEwJA
- fL8mZiZXan/oBKrblAbplNcKWGRVD/3y65042PAEeghahlJMiYquV5DzZajuuT0wbJ5xQuZB01+X
- nfpFpBJ2dw==
- 公钥加密——私钥解密
- 加密前: abc
- 解密后: abc
- 公钥:
- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdOj40yEB48XqWxmPILmJAc7UecIN7F32etSHF
- 9rwbuEh3+iTPOGSxhoSQpOED0vOb0ZIMkBXZSgsxLaBSin2RZ09YKWRjtpCA0kDkiD11gj4tzTiM
- l9qq1kwSK7ZkGAgodEn3yIILVmQDuEImHOXFtulvJ71ka07u3LuwUNdB/wIDAQAB
- 私钥:
- MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAN06PjTIQHjxepbGY8guYkBztR5w
- g3sXfZ61IcX2vBu4SHf6JM84ZLGGhJCk4QPS85vRkgyQFdlKCzEtoFKKfZFnT1gpZGO2kIDSQOSI
- PXWCPi3NOIyX2qrWTBIrtmQYCCh0SffIggtWZAO4QiYc5cW26W8nvWRrTu7cu7BQ10H/AgMBAAEC
- gYEAz2JWBizjI31bqhP4XiP9PuY5F3vqBW4T+L9cFbQiyumKJc58yzTWUAUGKIIn3enXLG7dNqGr
- mbJro4JeFIJ3CiVDpXR9+FluIgI4SXm7ioGKF2NOMA9LR5Fu82W+pLfpTN2y2SaLYWEDZyp53BxY
- j9gUxaxi1MQs+C1ZgDF2xmECQQDy70bQntbRfysP+ppCtd56YRnES1Tyekw0wryS2tr+ivQJl7JF
- gp5rPAOXpgrq36xHDwUspQ0sJ0vj0O7ywxr1AkEA6SAaLhrJJrYucC0jxwAhUYyaPN+aOsWymaRh
- 9jA/Wc0wp29SbGTh5CcMuGpXm1g0M+FKW3dGiHgS3rVUKim4owJAbnxgapUzAgiiHxxMeDaavnHW
- 9C2GrtjsO7qtZOTgYI/1uT8itvZW8lJTF+9OW8/qXE76fXl7ai9dFnl5kzMk2QJBALfHz/vCsArt
- mkRiwY6zApE4Z6tPl1V33ymSVovvUzHnOdD1SKQdD5t+UV/crb3QVi8ED0t2B0u0ZSPfDT/D7kMC
- QDpwdj9k2F5aokLHBHUNJPFDAp7a5QMaT64gv/d48ITJ68Co+v5WzLMpzJBYXK6PAtqIhxbuPEc2
- I2k1Afmrwyw=
- 私钥加密——公钥解密
- 加密前: sign
- 解密后: sign
- 私钥签名——公钥验证签名
- 签名:
- ud1RsIwmSC1pN22I4IXteg1VD2FbiehKUfNxgVSHzvQNIK+d20FCkHCqh9djP3h94iWnIUY0ifU+
- mbJkhAl/i5krExOE0hknOnPMcEP+lZV1RbJI2zG2YooSp2XDleqrQk5e/QF2Mx0Zxt8Xsg7ucVpn
- i3wwbYWs9wSzIf0UjlM=
- 状态:
- true
公钥: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYU/+I0+z1aBl5X6DUUOHQ7FZpmBSDbKTtx89JEcB64jFCkunELT8qiKly7fzEqD03g8ALlu5XvX+bBqHFy7YPJJP0ekE2X3wjUnh2NxlqpH3/B/xm1ZdSlCwDIkbijhBVDjA/bu5BObhZqQmDwIxlQInL9oVz+o6FbAZCyHBd7wIDAQAB私钥: MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJhT/4jT7PVoGXlfoNRQ4dDsVmmYFINspO3Hz0kRwHriMUKS6cQtPyqIqXLt/MSoPTeDwAuW7le9f5sGocXLtg8kk/R6QTZffCNSeHY3GWqkff8H/GbVl1KULAMiRuKOEFUOMD9u7kE5uFmpCYPAjGVAicv2hXP6joVsBkLIcF3vAgMBAAECgYBvZHWoZHmS2EZQqKqeuGr58eobG9hcZzWQoJ4nq/CarBAjw/VovUHE490uK3S9ht4FW7Yzg3LV/MB06Huifh6qf/X9NQA7SeZRRC8gnCQk6JuDIEVJOud5jU+9tyumJakDKodQ3Jf2zQtNr+5ZdEPluwWgv9c4kmpjhAdyMuQmYQJBANn6pcgvyYaia52dnu+yBUsGkaFfwXkzFSExIbi0MXTkhEb/ER/DrLytukkUu5S5ecz/KBa8U4xIslZDYQbLz5ECQQCy5dutt7RsxN4+dxCWn0/1FrkWl2G329Ucewm3QU9CKu4D+7Kqdj+Ha3lXP8F0Etaaapi7+EfkRUpukn2ItZV/AkEAlk+I0iphxT1rCB0Q5CjWDY5SDf2B5JmdEG5Y2o0nLXwG2w44OLct/k2uD4cEcuITY5Dvi/4BftMCZwm/dnhEgQJACIktJSnJwxLVo9dchENPtlsCM9C/Sd2EWpqISSUlmfugZbJBwR5pQ5XeMUqKeXZYpP+HEBj1nS+tMH9u2/IGEwJAfL8mZiZXan/oBKrblAbplNcKWGRVD/3y65042PAEeghahlJMiYquV5DzZajuuT0wbJ5xQuZB01+XnfpFpBJ2dw==公钥加密——私钥解密加密前: abc解密后: abc公钥: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdOj40yEB48XqWxmPILmJAc7UecIN7F32etSHF9rwbuEh3+iTPOGSxhoSQpOED0vOb0ZIMkBXZSgsxLaBSin2RZ09YKWRjtpCA0kDkiD11gj4tzTiMl9qq1kwSK7ZkGAgodEn3yIILVmQDuEImHOXFtulvJ71ka07u3LuwUNdB/wIDAQAB私钥: MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAN06PjTIQHjxepbGY8guYkBztR5wg3sXfZ61IcX2vBu4SHf6JM84ZLGGhJCk4QPS85vRkgyQFdlKCzEtoFKKfZFnT1gpZGO2kIDSQOSIPXWCPi3NOIyX2qrWTBIrtmQYCCh0SffIggtWZAO4QiYc5cW26W8nvWRrTu7cu7BQ10H/AgMBAAECgYEAz2JWBizjI31bqhP4XiP9PuY5F3vqBW4T+L9cFbQiyumKJc58yzTWUAUGKIIn3enXLG7dNqGrmbJro4JeFIJ3CiVDpXR9+FluIgI4SXm7ioGKF2NOMA9LR5Fu82W+pLfpTN2y2SaLYWEDZyp53BxYj9gUxaxi1MQs+C1ZgDF2xmECQQDy70bQntbRfysP+ppCtd56YRnES1Tyekw0wryS2tr+ivQJl7JFgp5rPAOXpgrq36xHDwUspQ0sJ0vj0O7ywxr1AkEA6SAaLhrJJrYucC0jxwAhUYyaPN+aOsWymaRh9jA/Wc0wp29SbGTh5CcMuGpXm1g0M+FKW3dGiHgS3rVUKim4owJAbnxgapUzAgiiHxxMeDaavnHW9C2GrtjsO7qtZOTgYI/1uT8itvZW8lJTF+9OW8/qXE76fXl7ai9dFnl5kzMk2QJBALfHz/vCsArtmkRiwY6zApE4Z6tPl1V33ymSVovvUzHnOdD1SKQdD5t+UV/crb3QVi8ED0t2B0u0ZSPfDT/D7kMCQDpwdj9k2F5aokLHBHUNJPFDAp7a5QMaT64gv/d48ITJ68Co+v5WzLMpzJBYXK6PAtqIhxbuPEc2I2k1Afmrwyw=私钥加密——公钥解密加密前: sign解密后: sign私钥签名——公钥验证签名签名:ud1RsIwmSC1pN22I4IXteg1VD2FbiehKUfNxgVSHzvQNIK+d20FCkHCqh9djP3h94iWnIUY0ifU+mbJkhAl/i5krExOE0hknOnPMcEP+lZV1RbJI2zG2YooSp2XDleqrQk5e/QF2Mx0Zxt8Xsg7ucVpni3wwbYWs9wSzIf0UjlM=状态:true
简要总结一下,使用公钥加密、私钥解密,完成了乙方到甲方的一次数据传递,通过私钥加密、公钥解密,同时通过私钥签名、公钥验证签名,完成了一次甲方到乙方的数据传递与验证,两次数据传递完成一整套的数据交互!
类似数字签名,数字信封是这样描述的:
数字信封
数字信封用加密技术来保证只有特定的收信人才能阅读信的内容。
流程:
信息发送方采用对称密钥来加密信息,然后再用接收方的公钥来加密此对称密钥(这部分称为数字信封),再将它和信息一起发送给接收方;接收方先用相应的私钥打开数字信封,得到对称密钥,然后使用对称密钥再解开信息。 -
典型的非对称加密算法 RSA
2016-07-21 11:13:00RES算法仅仅需要一套秘钥既可以完成加密/解密算法,并且公钥的秘钥长度明显的小于私钥的秘钥长度,支持“公钥加密,私钥解密”和“私钥加密,公钥解密”这两项加密解密原则。 代码样例: package encrypt.util...ps:
RES算法仅仅需要一套秘钥既可以完成加密/解密算法,并且公钥的秘钥长度明显的小于私钥的秘钥长度,支持“公钥加密,私钥解密”和“私钥加密,公钥解密”这两项加密解密原则。
代码样例:
package encrypt.util;
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.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;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
/**
* RSA安全编码组件
* @author admin
*
*/
public class RSACoder {
//非对称加密秘钥算法
private static final String KEY_ALGORITHM = "RSA";
//公钥
private static final String PUBLIC_KEY = "RSAPublicKey";
//私钥
private static final String PRIVATE_KEY = "RSAPrivateKey";
//RSA秘钥长度 默认1024
private static final int KEY_SIZE = 1024;
//私钥解密
/**
* @param data 待解密的数据
* @param key 私钥
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] data,byte[] key) throws Exception{
//取的私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//生产私钥对象
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
//对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
//执行
return cipher.doFinal(data);
}
/**
* @param data 待加密数据
* @param key 公钥
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data,byte[] key) throws Exception{
//取的公钥
X509EncodedKeySpec X509KeySpec = new X509EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//生产公钥对象
PublicKey publicKey = keyFactory.generatePublic(X509KeySpec);
//对数据进行加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
//执行
return cipher.doFinal(data);
}
/**取的私钥
* @param keyMap 秘钥map
* @return byte[] 私钥
*/
public static byte[] getPrivateKey(Map<String,Object> keyMap){
Key key = (Key)keyMap.get(PRIVATE_KEY);
return key.getEncoded();
}
/**取的公钥
* @param keyMap 秘钥map
* @return byte[] 公钥
*/
public static byte[] getPublicKey(Map<String,Object> keyMap){
Key key = (Key)keyMap.get(PUBLIC_KEY);
return key.getEncoded();
}
private static Map<String,Object> initKey() throws Exception{
//实例化秘钥生产器
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
//初始化秘钥生产器
keyPairGen.initialize(KEY_SIZE);
//生产秘钥对
KeyPair keyPair = keyPairGen.generateKeyPair();
//公钥
RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
//秘钥
RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
//封装秘钥
Map<String,Object> keyMap = new HashMap<String,Object>();
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
* 将16进制字符串还原为字节数组.
*/
private static final byte[] hexStrToBytes(String s) {
byte[] bytes;
bytes = new byte[s.length() / 2];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2), 16);
}
return bytes;
}
public static void main(String[] args) throws Exception {
/* Map<String,Object> keyMap = RSACoder.initKey();
byte[] privateKey = RSACoder.getPrivateKey(keyMap);
byte[] publicKey = RSACoder.getPublicKey(keyMap);
//Hex.encodeHex 做16进制编码处理
System.out.println("16进制 公钥字符串:\t"+new String(Hex.encodeHex(publicKey)));
System.out.println("16进制 私钥字符串:\t"+new String(Hex.encodeHex(privateKey)));*/
String privateKeyString = "30820276020100300d06092a864886f70d0101010500048202603082025c02010002818100820afd22bdd36cb75ef8db1a970d50ca352d57eecaa28779a559f626bf9182f0f986a2ea251f76040616032dc739e8558c0dfdfa82bef0203e8412bb2cb0dcaf7f568f100ce05f7bb239a6a4cbd7c1ed8041ea6f3b0c641c94f71228320584ba871012df218799b09f638478b9233bf594faa22d30d792a46b58459a52a1e1ef02030100010281803f5d97671c542f3f52d9b3f9caecc41723be4a80a2e07b5efd014efe268e82dd64d903fd4fc57abe0f311eaf69ca7fb95f9b59cc7d750890cda59172ff1dd70a3a7dae06661b1b7d5785a5153e4716b6c8fe1e2d8f8afc31e97b29d5a59365379a8949ebdf6543d293ec87a43d63ffa6507aa20dd5995efbdaa28c6198991231024100f8a68afdd0a358e2314d35c47a814b548383e2ce53e3eeff18ee844c8983ff40a0c80a4560efb0ffbd1c8b7092b38d75fa3190798c648b73825b11401a44d09502410085e2fb1bad7ffbad70cd6d992f22f504f4d09217b9eca3e4793810cb2a389cd828f091cd625fbc3fa0da7b0178dc3fcdbb94dc77db9c051ceb80c79d7060b373024100bb8c22da3f3c761666496e7cbc4a399f8d7334e79baf18dda0d887419397d437d30e0f71352495c4cfc7700581219d5997553b3bf301038e248cbbfe35d221e10240237c4785cc74716644d18dccddfb6be98661897714662e022e46b7dcc13204101eb9b44b35599e7156d6d167507b3fc5ed83c4f35797809b6ba7d4405c3aa515024055daef13aa8d7ccc927df4b1013e02a148666fece687a8be06a6c9beccf2055c96e0f0f4911fbdffdcf948a886c9e879a828f9962df0cf60b2bcf1d0a2098a8a";
String publicKeyString = "30819f300d06092a864886f70d010101050003818d0030818902818100820afd22bdd36cb75ef8db1a970d50ca352d57eecaa28779a559f626bf9182f0f986a2ea251f76040616032dc739e8558c0dfdfa82bef0203e8412bb2cb0dcaf7f568f100ce05f7bb239a6a4cbd7c1ed8041ea6f3b0c641c94f71228320584ba871012df218799b09f638478b9233bf594faa22d30d792a46b58459a52a1e1ef0203010001";
byte[] privateKey = hexStrToBytes(privateKeyString);
byte[] publicKey = hexStrToBytes(publicKeyString);
System.out.println("公钥:\t"+Base64.encodeBase64String(publicKey));
System.out.println("私钥:\t"+Base64.encodeBase64String(privateKey));
String str = "RSA";
byte[] inputStr = str.getBytes();
System.out.println("原文:\t"+str);
//公钥加密
byte[] endcryptData = RSACoder.encryptByPublicKey(inputStr, publicKey);
System.out.println("加密后:\t"+Base64.encodeBase64String(endcryptData));
//私钥解密
byte[] decryptData = RSACoder.decryptByPrivateKey(endcryptData, privateKey);
String decryptStr = new String(decryptData);
System.out.println("解密后:\t"+decryptStr);
}
} -
密码技术学习(6.2.2)-非对称加密在Java中的使用-RSA(典型非对称加密算法)
2018-08-22 11:20:47RSA(典型非对称加密算法) RSACoder工具类 RSACoderTest 参考资料 本系列其他文章 RSA(典型非对称加密算法) 之前介绍了DH算法,现在我们来介绍RSA算法。 在公开密钥密码体制中,加密密钥(即公开密钥)PK...文章目录
RSA(典型非对称加密算法)
之前介绍了DH算法,现在我们来介绍RSA算法。
在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,由于无法计算出大数n的欧拉函数phi(N),所以不能根据PK计算出SK。百度百科
基本上所有的非对称加密都是基于数学难题(基本上无解),而RSA算法是基于大数因数分解难题。即将两个大素数相乘很容易,但是想要将相乘的结果分解为两个大素数是非常困难(几乎不可能)。
RSACoder工具类
import java.security.GeneralSecurityException; 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.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 shaozuo * @date 2018/08/01 */ public final class RSACoder { public static final String ALGORITHM_NAME = "RSA"; private RSACoder() { } private static final int KEY_SIZE = 512; private static final String PUBLIC_KEY = "public_key"; private static final String PRIVATE_KEY = "private_key"; /** * 初始化公钥 * * @return Map 密钥map * @throws Exception */ public static Map<String, Object> initKey() throws Exception { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM_NAME); keyPairGenerator.initialize(KEY_SIZE); KeyPair keyPair = keyPairGenerator.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); Map<String, Object> keyMap = new HashMap<>(); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } public static byte[] getPrivateKey(Map<String, Object> keyMap) { Key key = (Key) keyMap.get(PRIVATE_KEY); return key.getEncoded(); } public static byte[] getPublicKey(Map<String, Object> keyMap) { Key key = (Key) keyMap.get(PUBLIC_KEY); return key.getEncoded(); } /** * 使用公钥加密数据 * * @param data * 待加密数据 * @param encodedPublicKey * 公钥 * @return * @throws GeneralSecurityException */ public static byte[] encyptByPublicKey(byte[] data, byte[] encodedPublicKey) throws GeneralSecurityException { X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(encodedPublicKey); KeyFactory factory = KeyFactory.getInstance(ALGORITHM_NAME); PublicKey publicKey = factory.generatePublic(encodedKeySpec); Cipher cipher = Cipher.getInstance(factory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 使用私钥加密数据 * * @param data * 待加密数据 * @param encodedPublicKey * 私钥 * @return * @throws GeneralSecurityException */ public static byte[] encyptByPrivateKey(byte[] data, byte[] encodedPrivateKey) throws GeneralSecurityException { PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey); KeyFactory factory = KeyFactory.getInstance(ALGORITHM_NAME); PrivateKey privateKey = factory.generatePrivate(encodedKeySpec); Cipher cipher = Cipher.getInstance(factory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 使用公钥解密数据 * * @param data * 待解密数据 * @param encodedPublicKey * 公钥 * @return * @throws GeneralSecurityException */ public static byte[] decyptByPublicKey(byte[] data, byte[] encodedPublicKey) throws GeneralSecurityException { X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(encodedPublicKey); KeyFactory factory = KeyFactory.getInstance(ALGORITHM_NAME); PublicKey publicKey = factory.generatePublic(encodedKeySpec); Cipher cipher = Cipher.getInstance(factory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 使用私钥解密数据 * * @param data * 待解密数据 * @param encodedPublicKey * 私钥 * @return * @throws GeneralSecurityException */ public static byte[] decyptByPrivateKey(byte[] data, byte[] encodedPrivateKey) throws GeneralSecurityException { PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey); KeyFactory factory = KeyFactory.getInstance(ALGORITHM_NAME); PrivateKey privateKey = factory.generatePrivate(encodedKeySpec); Cipher cipher = Cipher.getInstance(factory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } }
RSACoderTest
import static org.junit.Assert.assertEquals; import java.util.Map; import org.apache.commons.codec.binary.Base64; import org.junit.Before; import org.junit.Test; public class RSACoderTest { // 公钥 private byte[] publicKey; // 私钥 private byte[] privateKey; String rawStrForPri = "RSA 私钥加密-公钥解密"; String rawStrForPub = "RSA 公钥加密-私钥解密"; @Before public final void initKey() throws Exception { Map<String, Object> keyMap = RSACoder.initKey(); publicKey = RSACoder.getPublicKey(keyMap); privateKey = RSACoder.getPrivateKey(keyMap); System.out.println("公钥: " + Base64.encodeBase64String(publicKey)); System.out.println("私钥: " + Base64.encodeBase64String(privateKey)); } @Test public void test() throws Exception { System.out.println("待加密数据:" + rawStrForPri); System.out.println("原文:" + rawStrForPri); byte[] encodeData = RSACoder.encyptByPrivateKey(rawStrForPri.getBytes(), privateKey); System.out.println("加密数据: " + Base64.encodeBase64String(encodeData)); byte[] decodeData = RSACoder.decyptByPublicKey(encodeData, publicKey); String output = new String(decodeData); System.out.println("解密数据:" + output); assertEquals(rawStrForPri, output); // -----公钥加密 System.out.println("待加密数据:" + rawStrForPub); System.out.println("原文:" + rawStrForPub); encodeData = RSACoder.encyptByPublicKey(rawStrForPub.getBytes(), publicKey); System.out.println("加密数据: " + Base64.encodeBase64String(encodeData)); decodeData = RSACoder.decyptByPrivateKey(encodeData, privateKey); output = new String(decodeData); System.out.println("解密数据:" + output); assertEquals(rawStrForPub, output); } }
参考资料
关于本章内容,参考了一下书籍和文章
本系列其他文章
-
典型非对称加密算法RSA(Java)
2016-11-10 20:01:47DH算法的诞生为后续非对称加密算法奠定了基础,较为典型的对称加密算法(如EIGamal、RSA、ECC算法等)都是在DH算法提出后相继提出的,而且其算法核心都源于数学问题。 RSA算法基于大数因子分解难题,而EIGamal...典型非对称加密算法RSA
DH算法的诞生为后续非对称加密算法奠定了基础,较为典型的非对称加密算法(如EIGamal、RSA、ECC算法等)都是在DH算法提出后相继提出的,而且其算法核心都源于数学问题。
RSA算法基于大数因子分解难题,而EIGamal算法和ECC算法则是基于离散对数难题。
1.简述
1978年,美国麻省理工学院(MIT)的Ron Rivest、Adi Shamir和Leonand Adleman三位学者提出了一种新的非对称加密算法,这种算法以这三位学者的姓氏开头字母命名,被称为RSA算法。
RSA算法是唯一被广泛采用并且实现的通用公开加密算法,目前已经成为通用非对称加密算法国际标准。不仅如此,RSA算法既可用于数据加密也可用于数字签名。
RSA算法把非对称加密算法推向了一个高潮,但它并非没有缺点。相比DES以及其他对称加密算法而言,RSA算法要慢得多。作为加密算法,尤其作为非对称加密算法的典型,针对RSA算法的破解自诞生之日起就从未停止过。
1999年,RSA-155(512位)被成功分解,历时5个月。
2002年,RSA-158也被成功因数分解。
当然,基于大数因子分解数学难题的非对称加密算法仅有RSA算法这一种,但是这不代表RSA算法后继无人。基于离散对数问题的非对称加密算法包括ElGamal和ECC两种算法,他们同样是优秀的非对称加密算法。
2.模型分析
以消息传递模型为例,阐述基于RSA算法的消息传递模型是如何工作的。
RSA算法代表了真正的非对称加密算法,其操作较之DH算法更简单。在构建密钥对方面,RSA算法就相当简单。如图1所示。
在图1中,以甲乙两方收发信息为例。甲方作为信息的发送方,乙方作为信息的接收方。假设甲乙双方在消息传递之前已将RSA算法作为消息传递的加密算法。为了完成加密消息传递,甲乙双方需要以下操作:
1)由消息发送的一方构建密钥对,这里由甲方完成。
2)由消息发送的一方公布公钥至消息接收方,这里由甲方将公钥公布给乙方。
完成这两步操作后,甲乙双方就可以进行加密消息传递了,如图2和图3所示。
这里需要注意的:甲方向乙方发送数据时,使用私钥对数据进行加密处理;乙方接收到加密数据后,使用公钥对数据进行解密处理。
需要注意,在非对称加密算法领域中,对于私钥加密的数据,只能使用公钥解密,简言之“私钥加密,公钥解密”。
相对于“私钥加密,公钥解密”的实现,RSA算法提供了另一种加密/解密方式“公钥加密,私钥解密”。这使得乙方可以使用公钥加密数据,如图3所示。
甲方可以向乙方发送加密消息,乙方也同样可以向甲方发送加密消息。在图3中,乙方使用公钥加密信息,甲方使用私钥对加密信息进行解密。这是一种“公钥加密,私钥解密”的加密解密方式。
3.实现
1)RSA算法实现(RSACoder.java)
package rsa; 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.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; import javax.security.auth.x500.X500Principal; import org.bouncycastle.jce.X509KeyUsage; import org.bouncycastle.x509.X509Attribute; public abstract class RSACoder { //非崔晨加密算法 private static final String KEY_ALGORITHM = "RSA"; //公钥 private static final String PUBLIC_KEY = "RSAPublicKey"; //私钥 private static final String PRIVATE_KEY = "RSAPrivateKey"; //密钥长度 private static final int KEY_SIZE = 1024; /** * 私钥解密 * @param data 待解密数据 * @param key 私钥 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception{ //取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); //生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); //对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 公钥解密 * @param data 待解密数据 * @param key 公钥 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception{ //取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); //生成公钥 PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); //对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 私钥加密 * @param data 待加密数据 * @param key 私钥 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception{ //取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); //生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); //对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 公钥加密 * @param data 待加密数据 * @param key 公钥 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception{ //取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); //生成密钥 PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); //加密数据 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 取得私钥 * @param keyMap 私钥Map * @return byte[] 私钥 * @throws Exception */ public static byte[] getPrivateKey(Map<String, Object> keyMap) throws Exception{ Key key = (Key)keyMap.get(PRIVATE_KEY); return key.getEncoded(); } /** * 取得公钥 * @param keyMap 公钥Map * @return byte[] 公钥 * @throws Exception */ public static byte[] getPublicKey(Map<String, Object> keyMap) throws Exception{ Key key = (Key)keyMap.get(PUBLIC_KEY); return key.getEncoded(); } /** * 初始化密钥 * @return Map 密钥Map * @throws Exception */ public static Map<String, Object> initKey() throws Exception{ //实例化密钥对生成器 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM); //初始化密钥对生成器 keyPairGenerator.initialize(KEY_SIZE); //生成密钥对 KeyPair keyPair = keyPairGenerator.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; } }
2)RSA测试(RSATest.java)package rsa; import java.util.Map; import org.apache.commons.codec.binary.Base64; public class RSATest { //公钥 private static byte[] publicKey; //私钥 private static byte[] privateKey; /** * 初始化密钥 * @throws Exception */ public static void initKey() throws Exception{ //初始化密钥 Map<String, Object> keyMap = RSACoder.initKey(); publicKey = RSACoder.getPublicKey(keyMap); privateKey = RSACoder.getPrivateKey(keyMap); System.out.println("公钥:\n" + Base64.encodeBase64String(publicKey)); System.out.println("私钥:\n" + Base64.encodeBase64String(privateKey)); } public static void main(String[] args) throws Exception { // TODO Auto-generated method stub initKey(); System.out.println("\n~~~~~~~~~~~私钥加密,公钥解密~~~~~~~~~~~~~"); String inputStr = "坚强的意志和决心可以战胜一切困难,执着的信念和无畏的心灵才是最强大的武器。"; byte[] data1 = inputStr.getBytes(); System.out.println("原文:\n" + inputStr); //私钥加密 byte[] encodeData1 = RSACoder.encryptByPrivateKey(data1, privateKey); System.out.println("加密后:\n" + Base64.encodeBase64String(encodeData1)); //公钥解密 byte[] decodeData1 = RSACoder.decryptByPublicKey(encodeData1, publicKey); System.out.println("解密后:\n" + new String(decodeData1) + "\n"); initKey(); System.out.println("\n~~~~~~~~~~~公钥加密,私钥解密~~~~~~~~~~~~~"); byte[] data2 = inputStr.getBytes(); System.out.println("原文:\n" + inputStr); //公钥加密 byte[] encodeData2 = RSACoder.encryptByPublicKey(data2, publicKey); System.out.println("加密后:\n" + Base64.encodeBase64String(encodeData2)); //私钥解密 byte[] decodeData2 = RSACoder.decryptByPrivateKey(encodeData2, privateKey); System.out.println("解密后:\n" + new String(decodeData2)); } }
4.运行结果
-
Java加密技术非对称加密算法RSA.doc
2020-04-17 14:21:20Java加密技术 接下来我们介绍典型的非对称加密算法RSA RSA 这种算法1978年就出现了它是第一个既能用于数据加密也能用于数字签名的算法它易于理解和操作也很流行算法的名字以发明者的名字命名Ron Rivest, AdiShamir ... -
java双向加密算法_Java加密技术 非对称加密算法RSA 解析
2021-02-28 19:15:52介绍典型的非对称加密算法——RSARSA 这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard ... -
非对称加密算法原理及应用
2016-02-17 22:49:09[b]一、什么是非对称加密算法[/b] 加密和解密所用的密钥是不一样的,所以叫“非对称”。 非对称加密算法的这两个密钥,一个称为公钥,一个称为...RSA就是典型的非对称加密算法。 关于RSA算法的解释,最经典的... -
RSA —— 典型非对称加密算法
2019-08-18 12:22:00RSA —— JAVA代码 RSA —— 加密过程图解 ... (图1)构建RSA算法密匙对 (图2)甲方向乙方发送RSA加密数据 (图3) 乙方向甲方发送RSA加密数据 RSA —— 简述 已公开的或已知的... -
Java加密技术(四)——非对称加密算法RSA
2019-10-01 22:22:44接下来我们介绍典型的非对称加密算法——RSA RSA 这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, ... -
非对称加密算法RSA
2015-04-16 12:26:50接下来我们介绍典型的非对称加密算法——RSA RSA 这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, ... -
Java加密技术——非对称加密算法RSA
2013-04-23 11:01:38接下来我们介绍典型的非对称加密算法——RSA RSA 这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest... -
非对称加密算法之ElGamal算法
2020-10-20 17:19:22与典型非对称加密算法RSA算法相比,ElGamal算法则被称为常用非对称加密算法。 ElGamal既可用于加密,又可用于数字签名,是除RSA算法外最具代表性的公钥加密算法之一。 ElGamal算法就有较好的安全性,被广发应用。... -
RSA算法 非对称加密算法/数字签名算法
2015-12-09 16:42:40接下来我们介绍典型的非对称加密算法/数字签名算法——RSA RSA 这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命... -
Java加密技术四——非对称加密算法RSA
2016-05-04 16:50:00接下来我们介绍典型的非对称加密算法——RSA RSA 这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, ... -
非对称加密算法/数字签名算法——RSA
2013-08-25 00:15:37接下来我们介绍典型的非对称加密算法/数字签名算法——RSA RSA 这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名...