zoukankan      html  css  js  c++  java
  • 自己写的AES和RSA加密解密工具

    说明:本工具并未自己实现加密解密算法,使用jdk内置加解密工具和commons-codec工具进行加解密

      6 import java.security.Key;
      7 import java.security.KeyFactory;
      8 import java.security.KeyPair;
      9 import java.security.KeyPairGenerator;
     10 import java.security.NoSuchAlgorithmException;
     11 import java.security.PrivateKey;
     12 import java.security.PublicKey;
     13 import java.security.SecureRandom;
     14 import java.security.Signature;
     15 import java.security.interfaces.RSAPrivateKey;
     16 import java.security.interfaces.RSAPublicKey;
     17 import java.security.spec.InvalidKeySpecException;
     18 import java.security.spec.PKCS8EncodedKeySpec;
     19 import java.security.spec.X509EncodedKeySpec;
     20 import java.util.HashMap;
     21 import java.util.Map;
     22 import java.util.zip.CRC32;
     23 
     24 import javax.crypto.Cipher;
     25 import javax.crypto.KeyGenerator;
     26 import javax.crypto.NoSuchPaddingException;
     27 import javax.crypto.SecretKey;
     28 import javax.crypto.spec.SecretKeySpec;
     29 
     30 import org.apache.commons.codec.binary.Base64;
     31 
     32 /**
     33  * @ClassName: EncryptUtils
     34  * @Description: 加密、解密、压缩工具
     35  * @author: liuyx
     36  * @date: 2016年5月10日上午9:07:42
     37  */
     38 public class EncryptUtils extends Base64 {
     39     public static final String KEY_ALGORITHM_RSA = "RSA";
     40     public static final String KEY_ALGORITHM_AES = "AES";
     41 
     42     private static final String PUBLIC_KEY = "RSAPublicKey";  
     43     private static final String PRIVATE_KEY = "RSAPrivateKey"; 
     44     
     45     public static final String SIGNATURE_ALGORITHM_MD5_RSA = "MD5withRSA";
     46     /**
     47      * 
     48      * @Title: getCRC32Value
     49      * @author:liuyx @date:2016年5月10日09:19:29
     50      * @Description: 获取字符串对应的重复概率较小的整形
     51      * @param str
     52      *            传入32位字符串
     53      * @return
     54      */
     55     public static String getCRC32Value(String str) {
     56         CRC32 crc32 = new CRC32();
     57         crc32.update(str.getBytes());
     58         return Long.toString(crc32.getValue());
     59     }
     60 
     61     /*AES相关------start*/
     62     /**
     63      * 
     64      * @Title: getAesRandomKeyString
     65      * @author:liuyx
     66      * @date:2016年5月10日上午9:30:15
     67      * @Description: 获取AES随机密钥字符串
     68      * @return
     69      */
     70     public static String getAESRandomKeyString() {
     71         // 随机生成密钥
     72         KeyGenerator keygen;
     73         try {
     74             keygen = KeyGenerator.getInstance(KEY_ALGORITHM_AES);
     75             SecureRandom random = new SecureRandom();
     76             keygen.init(random);
     77             Key key = keygen.generateKey();
     78             // 获取秘钥字符串
     79             String key64Str = encodeBase64String(key.getEncoded());
     80             return key64Str;
     81         } catch (NoSuchAlgorithmException e) {
     82             // TODO Auto-generated catch block
     83             // e.printStackTrace();
     84             return null;
     85         }
     86 
     87     }
     88 
     89     /**
     90      * 
     91      * @Title: encryptByAESAndBase64
     92      * @author:liuyx
     93      * @date:2016年5月10日上午9:40:37
     94      * @Description: 使用AES加密,并返回经过BASE64处理后的密文
     95      * @param base64EncodedAESKey
     96      *            经过BASE64加密后的AES秘钥
     97      * @param dataStr
     98      * @return
     99      */
    100     public static String encryptByAESAndBase64(String base64EncodedAESKey, String dataStr) {
    101         SecretKey secretKey = restoreAESKey(base64EncodedAESKey);
    102 
    103         // 初始化加密组件
    104         Cipher cipher;
    105         try {
    106             cipher = Cipher.getInstance(KEY_ALGORITHM_AES);
    107             cipher.init(Cipher.ENCRYPT_MODE, secretKey);
    108             // 加密后的数据,首先将字符串转为byte数组,然后加密,为便于保存先转为base64
    109             String encryptedDataStr = encodeBase64String(cipher.doFinal(dataStr.getBytes()));
    110             return encryptedDataStr;
    111         } catch (Exception e) {
    112             // e.printStackTrace();
    113             return null;
    114         }
    115     }
    116 
    117     /**
    118      * 
    119      * @Title: decryptByAESAndBase64
    120      * @author:liuyx
    121      * @date:2016年5月10日上午11:24:47
    122      * @Description: 使用AES解密,并返回经过BASE64处理后的密文
    123      * @param base64EncodedAESKey
    124      * @param encryptedDataStr
    125      * @return
    126      */
    127     public static String decryptByAESAndBase64(String base64EncodedAESKey, String encryptedDataStr) {
    128         SecretKey secretKey = restoreAESKey(base64EncodedAESKey);
    129         try {
    130             Cipher cipher = Cipher.getInstance(KEY_ALGORITHM_AES);
    131             // 将加密组件的模式改为解密
    132             cipher.init(Cipher.DECRYPT_MODE, secretKey);
    133             // 和上面的加密相反,先解base64,再解密,最后将byte数组转为字符串
    134             String decryptedDataStr = new String(cipher.doFinal(Base64.decodeBase64(encryptedDataStr)));
    135             return decryptedDataStr;
    136         } catch (Exception e) {
    137             // TODO: handle exception
    138             return null;
    139         }
    140 
    141     }
    142 
    143     /**
    144      * 
    145      * @Title: restoreAESKey
    146      * @author:liuyx
    147      * @date:2016年5月10日上午9:53:01
    148      * @Description: 还原BASE64加密后的AES密钥
    149      * @param base64EncodedAESKey
    150      * @return
    151      */
    152     public static SecretKey restoreAESKey(String base64EncodedAESKey) {
    153         // 还原秘钥字符串到秘钥byte数组
    154         byte[] keyByteArray = decodeBase64(base64EncodedAESKey);
    155         // 重新形成秘钥,SecretKey是Key的子类
    156         SecretKey secretKey = new SecretKeySpec(keyByteArray, KEY_ALGORITHM_AES);
    157         return secretKey;
    158     }
    159     
    160     /*AES相关------end*/
    161     
    162     
    163     /*RSA相关------start*/
    164     /**
    165      * 
    166      * @Title: getRSARandomKeyPair
    167      * @author:liuyx
    168      * @date:2016年5月10日上午10:00:04
    169      * @Description: 生成RSA密钥对
    170      * @return
    171      */
    172     public static Map getRSARandomKeyPair() {
    173         KeyPairGenerator keyPairGen;
    174         try {
    175             keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM_RSA);
    176             keyPairGen.initialize(512);  
    177             KeyPair keyPair = keyPairGen.generateKeyPair();  
    178             // 公钥  
    179             RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  
    180             // 私钥  
    181             RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); 
    182             
    183             String publicKeyStr = encodeBase64String(publicKey.getEncoded());
    184             String privateKeyStr = encodeBase64String(privateKey.getEncoded());
    185             
    186             Map<String, String> keyMap = new HashMap<String, String>(2);  
    187             keyMap.put(PUBLIC_KEY, publicKeyStr);  
    188             keyMap.put(PRIVATE_KEY, privateKeyStr); 
    189             return keyMap;
    190         } catch (NoSuchAlgorithmException e) {
    191             //e.printStackTrace();
    192             return null;
    193         }  
    194 
    195     }
    196     
    197     /**
    198      * 
    199      * @Title: encryptByRSAPublicKeyAndBase64
    200      * @author:liuyx
    201      * @date:2016年5月10日上午10:50:00
    202      * @Description: RSA公钥加密:使用RSA公钥(BASE64加密后的字符串)对数据进行加密
    203      * @param publicRSAKey
    204      * @param dataStr
    205      * @return
    206      */
    207     public static String encryptByRSAPublicKeyAndBase64(String publicRSAKey,String dataStr) {
    208         byte[] data = dataStr.getBytes();
    209         // 对公钥解密  
    210         Key decodePublicKey = restoreRSAPublicKeyFromBase64KeyEncodeStr(publicRSAKey);  
    211 
    212         // 对数据加密  
    213         Cipher cipher;
    214         try {
    215             cipher = Cipher.getInstance(KEY_ALGORITHM_RSA);
    216             cipher.init(Cipher.ENCRYPT_MODE, decodePublicKey);  
    217             byte[] encodedData = cipher.doFinal(data); 
    218             String encodedDataStr = encodeBase64String(encodedData);
    219             return encodedDataStr;
    220         } catch (Exception e) {
    221             // TODO Auto-generated catch block
    222             return null;
    223         }
    224 
    225     }
    226     /**
    227      * 
    228      * @Title: decryptByRSAPublicKeyAndBase64
    229      * @author:liuyx
    230      * @date:2016年5月10日上午10:56:03
    231      * @Description: RSA公钥解密:使用RSA公钥(BASE64加密后的字符串)对数据进行解密
    232      * @param publicRSAKey
    233      * @param encryptedDataStr
    234      * @return
    235      */
    236     public static String decryptByRSAPublicKeyAndBase64(String publicRSAKey, String encryptedDataStr) {
    237         //还原公钥  
    238         Key decodePublicKey = restoreRSAPublicKeyFromBase64KeyEncodeStr(publicRSAKey);  
    239         try {
    240             Cipher cipher = Cipher.getInstance(KEY_ALGORITHM_RSA);
    241             cipher.init(Cipher.DECRYPT_MODE, decodePublicKey); 
    242             byte[] decodedData = cipher.doFinal(Base64.decodeBase64(encryptedDataStr)); 
    243             String decodedDataStr = new String(decodedData);
    244             return decodedDataStr;
    245         } catch (Exception e) {
    246             // TODO: handle exception
    247             return null;
    248         }
    249 
    250     }
    251     
    252     /**
    253      * 
    254      * @Title: getSignFromEncryptedDataWithPrivateKey
    255      * @author:liuyx
    256      * @date:2016年5月10日上午11:08:13
    257      * @Description: 生成RSA签名:使用base64加密后的私钥和加密后的数据(byte数组形式),获取加密数据签名
    258      * @param privateRSAKey
    259      * @param encryotedDataStr
    260      * @return
    261      */
    262     public static String getSignFromEncryptedDataWithPrivateKey(String privateRSAKey,String encryotedDataStr) {
    263         byte[] data = decodeBase64(encryotedDataStr);
    264         //加密后的数据+私钥,生成签名
    265         Key decodePrivateKey = restoreRSAPrivateKeyFromBase64KeyEncodeStr(privateRSAKey);
    266         Signature signature;
    267         try {
    268             signature = Signature.getInstance(SIGNATURE_ALGORITHM_MD5_RSA);
    269             signature.initSign((PrivateKey)decodePrivateKey);  //用的是私钥
    270             signature.update(data);  //用的是加密后的数据字节数组
    271             //取得签名
    272             String sign = Base64.encodeBase64String((signature.sign())); 
    273             return sign;
    274         } catch (Exception e) {
    275             // TODO Auto-generated catch block
    276             e.printStackTrace();
    277             return null;
    278         }  
    279 
    280     }
    281     
    282     /**
    283      * 
    284      * @Title: verifySign
    285      * @author:liuyx
    286      * @date:2016年5月10日上午11:18:06
    287      * @Description: 验证RSA签名
    288      * @param publicRSAKey
    289      * @param sign
    290      * @param encryotedDataStr
    291      * @return
    292      */
    293     public static boolean verifySign(String publicRSAKey,String sign,String encryotedDataStr) {
    294         byte[] data = decodeBase64(encryotedDataStr);
    295         Key decodePublicKey = restoreRSAPublicKeyFromBase64KeyEncodeStr(publicRSAKey); 
    296         //初始化验证签名
    297         Signature signature;
    298         try {
    299             signature = Signature.getInstance(SIGNATURE_ALGORITHM_MD5_RSA);
    300             signature.initVerify((PublicKey )decodePublicKey);  //用的是公钥
    301             signature.update(data);  //用的是加密后的数据字节数组
    302             boolean ret = signature.verify(decodeBase64(sign));
    303             return ret;
    304         } catch (Exception e) {
    305             // TODO Auto-generated catch block
    306             e.printStackTrace();
    307         }
    308         
    309         return false;
    310     }
    311     
    312     /**
    313      * 
    314      * @Title: encryptByRSAPrivateKeyAndBase64
    315      * @author:liuyx
    316      * @date:2016年5月10日上午11:00:03
    317      * @Description: RSA私钥加密:使用RSA私钥(BASE64加密后的字符串)对数据进行加密
    318      * @param privateRSAKey
    319      * @param dataStr
    320      * @return
    321      */
    322     public static String encryptByRSAPrivateKeyAndBase64(String privateRSAKey,String dataStr) {
    323         byte[] data = dataStr.getBytes();
    324         // 对私钥解密  
    325         Key decodePrivateKey = restoreRSAPrivateKeyFromBase64KeyEncodeStr(privateRSAKey);  
    326 
    327         // 对数据加密  
    328         Cipher cipher;
    329         try {
    330             cipher = Cipher.getInstance(KEY_ALGORITHM_RSA);
    331             cipher.init(Cipher.ENCRYPT_MODE, decodePrivateKey);  
    332             byte[] encodedData = cipher.doFinal(data); 
    333             String encodedDataStr = encodeBase64String(encodedData);
    334             return encodedDataStr;
    335         } catch (Exception e) {
    336             // TODO Auto-generated catch block
    337             return null;
    338         }
    339 
    340     }
    341     
    342     /**
    343      * 
    344      * @Title: decryptByRSAPrivateKeyAndBase64
    345      * @author:liuyx
    346      * @date:2016年5月10日上午11:26:44
    347      * @Description: RSA私钥解密:使用RSA私钥(BASE64加密后的字符串)对数据进行解密
    348      * @param privateRSAKey
    349      * @param encryptedDataStr
    350      * @return
    351      */
    352     public static String decryptByRSAPrivateKeyAndBase64(String privateRSAKey, String encryptedDataStr) {
    353         //还原私钥  
    354         Key decodePrivateKey = restoreRSAPrivateKeyFromBase64KeyEncodeStr(privateRSAKey);  
    355         try {
    356             Cipher cipher = Cipher.getInstance(KEY_ALGORITHM_RSA);
    357             cipher.init(Cipher.DECRYPT_MODE, decodePrivateKey); 
    358             byte[] decodedData = cipher.doFinal(Base64.decodeBase64(encryptedDataStr)); 
    359             String decodedDataStr = new String(decodedData);
    360             return decodedDataStr;
    361         } catch (Exception e) {
    362             // TODO: handle exception
    363             return null;
    364         }
    365 
    366     }
    367     
    368     /*
    369      * 获取base64加密后的字符串的原始公钥
    370      */
    371     private static Key restoreRSAPublicKeyFromBase64KeyEncodeStr(String keyStr) {
    372         byte[] keyBytes = Base64.decodeBase64(keyStr);  
    373         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);  
    374         Key publicKey = null;
    375         try {
    376             KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM_RSA);
    377             publicKey = keyFactory.generatePublic(x509KeySpec);  
    378         } catch (Exception e) {
    379             // TODO Auto-generated catch block
    380             e.printStackTrace();
    381         }  
    382         return publicKey;
    383     }
    384     
    385     /*
    386      * 获取base64加密后的字符串的原始私钥
    387      */
    388     private static Key restoreRSAPrivateKeyFromBase64KeyEncodeStr(String keyStr) {
    389         byte[] keyBytes = Base64.decodeBase64(keyStr); 
    390         // 取得私钥  
    391         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);  
    392         
    393         Key privateKey=null;
    394         try {
    395             KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM_RSA);
    396             privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
    397         } catch (Exception e) {
    398             // TODO Auto-generated catch block
    399             e.printStackTrace();
    400         }  
    401         return privateKey;
    402     }
    403     /*RSA相关------end*/
    404     
    405     public static void main(String[] args) {
    406         String str = "981hf98w7`9h5fdjk09qy56hty4gahguewqpg{}d[}]df2,,,1,4";
    407         System.out.println("原字符串:"+str);
    408         String aesKey = EncryptUtils.getAESRandomKeyString();
    409         String aesEncryptedStr = EncryptUtils.encryptByAESAndBase64(aesKey, str);
    410         System.out.println("AES加密后:"+aesEncryptedStr);
    411         String aesDecryptedStr = EncryptUtils.decryptByAESAndBase64(aesKey, aesEncryptedStr);
    412         System.out.println("AES解密后:"+aesDecryptedStr);
    413         
    414         Map<String,String> keyPair = EncryptUtils.getRSARandomKeyPair();
    415         String publicRSAKey = keyPair.get(EncryptUtils.PUBLIC_KEY);
    416         String privateRSAKey = keyPair.get(EncryptUtils.PRIVATE_KEY);
    417         
    418         String encryptedStr = EncryptUtils.encryptByRSAPublicKeyAndBase64(publicRSAKey, str);
    419         System.out.println("公钥加密后:"+encryptedStr);
    420         String decryptedStr = EncryptUtils.decryptByRSAPrivateKeyAndBase64(privateRSAKey, encryptedStr);
    421         System.out.println("私钥解密后:"+decryptedStr);
    422         
    423         encryptedStr = EncryptUtils.encryptByRSAPrivateKeyAndBase64(privateRSAKey, str);
    424         System.out.println("私钥加密后:"+encryptedStr);
    425         
    426         String sign = EncryptUtils.getSignFromEncryptedDataWithPrivateKey(privateRSAKey, encryptedStr);
    427         System.out.println("签名:"+sign);
    428         boolean verifyResult = EncryptUtils.verifySign(publicRSAKey, sign, encryptedStr);
    429         System.out.println("签名验证结果:"+verifyResult);
    430         
    431         decryptedStr = EncryptUtils.decryptByRSAPublicKeyAndBase64(publicRSAKey, encryptedStr);
    432         System.out.println("公钥解密后:"+decryptedStr);
    433     }
    434 }

     异常的处理都是简单的返回了null,实际使用时请自行调整异常处理。

  • 相关阅读:
    Lesson 3 Nehe
    Lesson 2 Nehe
    Lesson 1 Nehe
    Lesson 1 Nehe
    JavaScript 字符串与数组转换函数[不用split与join]
    华中科大校长:教授被称为“叫兽”是教育的悲哀
    /etc/profile、~/.bash_profile等几个文件的执行过程
    cygwin下遇到system没有执行的问题
    发短信 汉字编码 utf-8 UCS-2BE
    UTF-8与UNICODE的关系及代码转换
  • 原文地址:https://www.cnblogs.com/flying607/p/5477887.html
Copyright © 2011-2022 走看看