JAVA 非对称加密算法RSA

jopen 10年前

非对称加密算法 RSA过程 : 以甲乙双方为例

1、初始化密钥 构建密钥对,生成公钥、私钥保存到keymap中
KeyPairGenerator ---> KeyPair --> RSAPublicKey、RSAPrivateKey
2、甲方使用私钥加密, 加密后在用私钥对加密数据进行数据签名,然后发送给乙方
RSACoder.encryptByPrivateKey(data, privateKey);
RSACoder.sign(encodedData, privateKey);
3、乙方则通过公钥验证签名的加密数据,如果验证正确则在通过公钥对加密数据进行解密
RSACoder.verify(encodedData, publicKey, sign);
RSACoder.decryptByPublicKey(encodedData, publicKey);
 4、乙方在通过公钥加密发送给甲方
RSACoder.encryptByPublicKey(decodedData, publicKey);
5、甲方通过私钥解密该数据
RSACoder.decryptPrivateKey(encodedData, privateKey);
流程图如下:

JAVA 非对称加密算法RSA

JAVA 非对称加密算法RSA

JAVA 非对称加密算法RSA

java代码实现如下:

package com.bank.utils;    import java.security.MessageDigest;    import javax.crypto.KeyGenerator;  import javax.crypto.Mac;  import javax.crypto.SecretKey;  import javax.crypto.spec.SecretKeySpec;    import sun.misc.BASE64Decoder;  import sun.misc.BASE64Encoder;    public abstract class Coder {   public static final String KEY_SHA = "SHA";   public static final String KEY_MD5 = "MD5";      /**        * MAC算法可选以下多种算法        *         * <pre>        * HmacMD5         * HmacSHA1         * HmacSHA256         * HmacSHA384         * HmacSHA512        * </pre>        */     public static final String KEY_MAC = "HmacMD5";      /**    * BASE64解密    * @param key    * @return    * @throws Exception    */   public static byte[] decryptBASE64( String key ) throws Exception{    return (new BASE64Decoder()).decodeBuffer(key);   }      /**    * BASE64加密    * @param key    * @return    * @throws Exception    */   public static String encryptBASE64( byte[] key) throws Exception{    return (new BASE64Encoder()).encodeBuffer(key);   }      /**    * MD5 加密    * @param data    * @return    * @throws Exception    */   public static byte[] encryptMD5( byte[] data) throws Exception {    MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);    md5.update(data);        return md5.digest();   }      /**    * SHA 加密    * @param data    * @return    * @throws Exception    */   public static byte[] encryptSHA( byte[] data) throws Exception {    MessageDigest sha = MessageDigest.getInstance(KEY_SHA);    sha.update(data);        return sha.digest();   }      /**        * 初始化HMAC密钥        *         * @return        * @throws Exception        */     public static String initMacKey() throws Exception{    KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);        SecretKey secretKey = keyGenerator.generateKey();    return encryptBASE64(secretKey.getEncoded());   }      /**    * HMAC  加密    * @param data    * @param key    * @return    * @throws Exception    */   public static byte[] encryptHMAC( byte[] data, String key) throws Exception{    SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);    Mac mac = Mac.getInstance(secretKey.getAlgorithm());    mac.init(secretKey);    return mac.doFinal(data);   }  }


package com.bank.utils;    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";      /**    * 用私钥对信息生成数字签名    * @param data 加密数据    * @param privateKey 私钥    * @return    * @throws Exception    */   public static String sign(byte[] data, String privateKey) throws Exception {    //解密由base64编码的私钥    byte[] keyBytes = decryptBASE64(privateKey);        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);        //取私钥对象    PrivateKey pKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);        //用私钥生成数字签名    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);    signature.initSign(pKey);    signature.update(data);        return encryptBASE64(signature.sign());   }      /**    * 校验数字签名    * @param data 加密数据    * @param publicKey 公钥    * @param sign 数字签名    * @return    * @throws Exception    */   public static boolean verify(byte[] data, String publicKey, String sign) throws Exception{        //解密有base64编码的公钥    byte[] keyBytes = decryptBASE64(publicKey);        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);        //取公钥对象    PublicKey pKey = keyFactory.generatePublic(keySpec);        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);    signature.initVerify(pKey);    signature.update(data);    //验证签名是否正常    return signature.verify(decryptBASE64(sign));   }      /**    * 解密     *  用私钥解密    * @param data 加密数据    * @param key    * @return    * @throws Exception    */   public static byte[] decryptPrivateKey(byte[] data, String key) throws Exception{    byte[] keyBytes = decryptBASE64(key);        //取得私钥    PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);    KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);    Key pKey = factory.generatePrivate(encodedKeySpec);        //对数据解密    Cipher cipher = Cipher.getInstance(factory.getAlgorithm());    cipher.init(Cipher.DECRYPT_MODE, pKey);        return cipher.doFinal(data);   }      /**    * 用公钥解密    * @param data    * @param key    * @return    * @throws Exception    */   public static byte[] decryptByPublicKey( byte[] data, String key) throws Exception{        //解密    byte[] keyBytes = decryptBASE64(key);        //取得公钥    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);    Key pKey = keyFactory.generatePublic(keySpec);        //对数据解密    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());    cipher.init(Cipher.DECRYPT_MODE, pKey);        return cipher.doFinal(data);   }      /**    * 用公钥加密    * @param data    * @param key    * @return    * @throws Exception    */   public static byte[] encryptByPublicKey( byte[] data, String key) throws Exception{        byte[] keyBytes = decryptBASE64(key);        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);    Key pKey = keyFactory.generatePublic(keySpec);            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());    cipher.init(Cipher.ENCRYPT_MODE, pKey);        return cipher.doFinal(data);   }      /**    * 用私钥加密    * @param data    * @param key    * @return    * @throws Exception    */   public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception{        byte[] keyBytes = decryptBASE64(key);        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);    Key privateKey = keyFactory.generatePrivate(keySpec);        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 keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);    keyPairGenerator.initialize(1024);        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(PRIVATE_KEY, privateKey);    keyMap.put(PUBLIC_KEY, publicKey);    return keyMap;   }  }


package com.bank.test;    import java.util.Map;    import org.junit.Assert;  import org.junit.Before;  import org.junit.Test;    import com.bank.utils.RSACoder;    public class RSACoderTest {   private String publicKey;   private String privateKey;   /*    * 非对称加密算法   RSA过程 : 以甲乙双方为例    *   1、初始化密钥 构建密钥对,生成公钥、私钥保存到keymap中    *     KeyPairGenerator ---> KeyPair  -->  RSAPublicKey、RSAPrivateKey    *   2、甲方使用私钥加密, 加密后在用私钥对加密数据进行数据签名,然后发送给乙方    *     RSACoder.encryptByPrivateKey(data, privateKey);    *     RSACoder.sign(encodedData, privateKey);    *   3、乙方则通过公钥验证签名的加密数据,如果验证正确则在通过公钥对加密数据进行解密    *     RSACoder.verify(encodedData, publicKey, sign);    *     RSACoder.decryptByPublicKey(encodedData, publicKey);        *     *   4、乙方在通过公钥加密发送给甲方    *     RSACoder.encryptByPublicKey(decodedData, publicKey);    *   5、甲方通过私钥解密该数据      *     RSACoder.decryptPrivateKey(encodedData, privateKey);        */   @Before   public void setUp() throws Exception {        Map<String , Object> keyMap = RSACoder.initKey();        publicKey = RSACoder.getPublicKey(keyMap);    privateKey = RSACoder.getPrivateKey(keyMap);        System.out.println("公钥:\n" + publicKey);    System.out.println("私钥:\n" + privateKey);   }   @Test   public void test() throws Exception{    String inputStr = "abc";    byte[] data = inputStr.getBytes();//每次的得到的字节数组是不一样的。    //第二步 私钥加密    byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);    //私钥进行数据签名    String sign = RSACoder.sign(encodedData, privateKey);        //第三步 公钥验证数字签名    boolean flag = RSACoder.verify(encodedData, publicKey, sign);    System.out.println("flag:" + flag);    //用公钥对数据解密    byte[] decodedData = RSACoder.decryptByPublicKey(encodedData, publicKey);        System.out.println("data:" + data + "加密数据:" + encodedData + "    解密数据:" + decodedData);    System.out.println("加密前数据-:" + new String(data) + "     解密后数据: " + new String(decodedData));        //第四步使用公钥加密数据    encodedData = RSACoder.encryptByPublicKey(decodedData, publicKey);        //第五步 使用私钥解密数据    decodedData = RSACoder.decryptPrivateKey(encodedData, privateKey);            System.out.println("data:" + data + "加密数据:" + encodedData + "    解密数据:" + decodedData);    System.out.println("加密前数据:" + inputStr + "     解密后数据: " + new String(decodedData));   }         @Test   public void test1() throws Exception{    System.out.println("私钥加密-----公钥解密");    String inputStr = "abc";    byte[] data = inputStr.getBytes();    System.out.println("data:" + data);        byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);    byte[] decodedData = RSACoder.decryptByPublicKey(encodedData, publicKey);       String outputStr = new String( decodedData );        System.out.println("加密前:" + inputStr +"\n 解密后:" + outputStr);        Assert.assertEquals(inputStr, outputStr);            System.out.println("私钥签名---公钥验证签名");    //产生签名    String sign = RSACoder.sign(encodedData, privateKey);    System.out.println("签名:\r" + sign);        //验证签名    boolean flag = RSACoder.verify(encodedData, publicKey, sign);        System.out.println("状态:\r" + flag);        Assert.assertTrue(flag);   }  }


</div>