非对称密码之RSA算法

来源:互联网 发布:大质数分解算法 编辑:程序博客网 时间:2024/05/18 03:35

1、RSA算法的简介

     由Ron Rivest、 Adi Shamir 和 Leonard Adleman三位学者提出的非对称加密算法。RSA 算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。它是第一个既能用于数据加密也能用于数字签名的算法。

2、RSA 数学原理

    (1)加解密公式
            RSA加密:密文 = 明文E mod N      公钥(E,N)
            RSA解密:明文 = 密文D mod N      私钥(D,N)
    (2)模拟生成密钥对
            1)求N:p=17 q=19           N=p*q = 323
            2)求L:L=lcm(p-1,q-1)=lcm(16,18) = 144
            3)求E:gcd(E,L)=1           E=5
            4)求D:E*D mod L = 1    D=29
                 公钥(5,323)     私钥(29,323)
             

    (3)加密
            密文 = 明文E mod N = 1235 mod 323 = 225
    (4)解密
            明文 = 密文D mod N = 22529 mod 323 = 123

3、JDK的实现

      

4、RSA算法编程步骤

     4.1  生成公钥和私钥

        

     4.2  加密/解密

         

5、RSA算法的实现

import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.util.HashMap;import java.util.Map;import javax.crypto.Cipher;public class RSAUtil {public static final String PUBLIC_KEY = "RSAPublicKey";public static final String PRIVATE_KEY = "RSAPrivateKey";public static final String KEY = "RSA";/** * 生成 RSA 的 公钥 和 私钥 *  * @return */public static Map<String, Object> initKey() {try {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY);keyPairGenerator.initialize(1024); // 512-65536 & 64的倍数KeyPair keyPair = keyPairGenerator.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;} catch (Exception e) {throw new RuntimeException(e);}}/** * 获取RSA的公钥 *  * @param keyMap * @return */public static RSAPublicKey getPublicKey(Map<String, Object> keyMap) {RSAPublicKey publicKey = (RSAPublicKey) keyMap.get(PUBLIC_KEY);return publicKey;}/** * 获取RSA的私钥 *  * @param keyMap * @return */public static RSAPrivateKey getPrivateKey(Map<String, Object> keyMap) {RSAPrivateKey privateKey = (RSAPrivateKey) keyMap.get(PRIVATE_KEY);return privateKey;}/** * 公钥加密 *  * @param data *            要加密的数据 * @param publicKey *            公钥 * @return * @throws Exception */public static byte[] encrypt(byte[] data, RSAPublicKey publicKey) {try {Cipher cipher = Cipher.getInstance(KEY);cipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] cipherBytes = cipher.doFinal(data);return cipherBytes;} catch (Exception e) {throw new RuntimeException(e);}}/** * 私钥解密 *  * @param data *            要解密的数据 * @param privateKey *            私钥 * @return * @throws Exception */public static byte[] decrypt(byte[] data, RSAPrivateKey privateKey) {try {Cipher cipher = Cipher.getInstance(KEY);cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] plainBytes = cipher.doFinal(data);return plainBytes;} catch (Exception e) {throw new RuntimeException(e);}}}


字节数组转16进制

public class BytesToHex {public static String fromBytesToHex(byte[] resultBytes) {StringBuilder builder = new StringBuilder();for (int i = 0; i < resultBytes.length; i++) {if (Integer.toHexString(0xFF & resultBytes[i]).length() == 1) {builder.append("0").append(Integer.toHexString(0xFF & resultBytes[i]));} else {builder.append(Integer.toHexString(0xFF & resultBytes[i]));}}return builder.toString();}}
测试代码

public class Test {// 待加密的明文public static final String DATA = "test";public static void main(String[] args) throws Exception {/* Test RSA */Map<String, Object> keyMap = RSAUtil.initKey();RSAPublicKey rsaPublicKey = RSAUtil.getPublicKey(keyMap);RSAPrivateKey rsaPrivateKey = RSAUtil.getPrivateKey(keyMap);System.out.println("RSA PublicKey : " + rsaPublicKey);System.out.println("RSA PrivateKey : " + rsaPrivateKey);byte[] rsaResult = RSAUtil.encrypt(DATA.getBytes(), rsaPublicKey);System.out.println(DATA + ">>>RSA 加密>>>"+ BytesToHex.fromBytesToHex(rsaResult));byte[] plainResult = RSAUtil.decrypt(rsaResult, rsaPrivateKey);System.out.println(DATA + ">>>RSA 解密>>>" + new String(plainResult));}}

1 0