java RSA加密解密

 java RSA加密解密


demo:

demo下载


其他环境相关:

最近为客户做了一个工具,需求:客户在命令行下,通过这个工具下载数据包;下载的数据包已加密,只有已登录的用户,才允许解密并使用数据包。


实现并不复杂,流程:

1、用户登录时,采用sha-1+n位随机码加密用户密码,提交服务器验证。

2、数据包已在服务器(PBEWithSHA1AndDESede)加密,用户根据数据包概要信息选择并下载数据包。

3、安装数据包时,需求用户输入密码,确认后执行解密+使用数据包。


在公司windows+linux测试后,到用户现场测试(AIX机器),发现程序报错,查来查去 发现IBM-JDK与Sun-JDK采用不同的加密提供者,采用Sun-JDK加密算法写的代码 在AIX要么加密算法提供者无法找到,要么密钥长度不对。


以下是两种jdk加密算法提供者信息,能看出明显不同。

---------------sun jdk1.5 加密算法提供信息
SUN 1.5 SUN (DSA key/parameter generation; DSA signing; SHA-1, MD5 digests; SecureRandom; X.509 certificates; JKS keystore; PKIX CertPathValidator; PKIX CertPathBuilder; LDAP, Collection CertStores)
SunRsaSign 1.5 Sun RSA signature provider
SunJSSE 1.5 Sun JSSE provider(PKCS12, SunX509 key/trust factories, SSLv3, TLSv1)
SunJCE 1.5 SunJCE Provider (implements RSA, DES, Triple DES, AES, Blowfish, ARCFOUR, RC2, PBE, Diffie-Hellman, HMAC)
SunJGSS 1.0 Sun (Kerberos v5)
SunSASL 1.5 Sun SASL provider(implements client mechanisms for: DIGEST-MD5, GSSAPI, EXTERNAL, PLAIN, CRAM-MD5; server mechanisms for: DIGEST-MD5, GSSAPI, CRAM-MD5)


---------------aix jdk1.5 加密算法提供信息
IBMJSSE2 1.5 IBM JSSE provider2 (implements IbmX509 key/trust factories, SSLv3,
TLSv1)
IBMJCE 1.2 IBMJCE Provider implements the following: HMAC-SHA1, MD2, MD5, MARS,
SHA, MD2withRSA, MD5withRSA, SHA1withRSA, RSA, SHA1withDSA, RC2, RC4, Seal)imple
ments the following:
Signature algorithms               : SHA1withDSA, SHA1withRSA, MD5withRSA, MD2wi
thRSA,
                                       SHA2withRSA, SHA3withRSA, SHA5withRSA
Cipher algorithms                  : Blowfish, AES, DES, TripleDES, PBEWithMD2An
dDES,
                                       PBEWithMD2AndTripleDES, PBEWithMD2AndRC2,
                                       PBEWithMD5AndDES, PBEWithMD5AndTripleDES,
                                       PBEWithMD5AndRC2, PBEWithSHA1AndDES
                                       PBEWithSHA1AndTripleDES, PBEWithSHA1AndRC
2
                                       PBEWithSHAAnd40BitRC2, PBEWithSHAAnd128Bi
tRC2
                                       PBEWithSHAAnd40BitRC4, PBEWithSHAAnd128Bi
tRC4
                                       PBEWithSHAAnd2KeyTripleDES, PBEWithSHAAnd
3KeyTripleDES
                                       Mars, RC2, RC4, ARCFOUR
                                       RSA, Seal
Message authentication code (MAC)  : HmacSHA1, HmacSHA256, HmacSHA384, HmacSHA51
2, HmacMD2, HmacMD5
Key agreement algorithm            : DiffieHellman
Key (pair) generator               : Blowfish, DiffieHellman, DSA, AES, DES, Tri
pleDES, HmacMD5,
                                       HmacSHA1, Mars, RC2, RC4, RSA, Seal, ARCF
OUR
Message digest                     : MD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512
Algorithm parameter generator      : DiffieHellman, DSA
Algorithm parameter                : Blowfish, DiffieHellman, AES, DES, TripleDE
S, DSA, Mars,
                                       PBEwithMD5AndDES, RC2
Key factory                        : DiffieHellman, DSA, RSA
Secret key factory                 : Blowfish, AES, DES, TripleDES, Mars, RC2, R
C4, Seal, ARCFOUR
                                       PKCS5Key, PBKDF1 and PBKDF2(PKCS5Derived
Key).
Certificate                        : X.509
Secure random                      : IBMSecureRandom
Key store                          : JCEKS, PKCS12KS (PKCS12), JKS
IBMJGSSProvider 1.5 IBMJGSSProvider supports Kerberos V5 Mechanism
IBMCertPath 1.1 IBMCertPath Provider implements the following:
CertificateFactory                : X.509
CertPathValidator              : PKIX
CertStore                      : Collection, LDAP
CertPathBuilder                : PKIX
IBMSASL 1.5 IBM SASL provider(implements client mechanisms for: DIGEST-MD5, GSSA
PI, EXTERNAL, PLAIN, CRAM-MD5; server mechanisms for: DIGEST-MD5, GSSAPI, CRAM-M
D5)




解决方法:

1、为IBM-JDK写专用程序,用IBM加密算法。 这种方法可能存在两种jdk加密结果不同的风险。

2、把Sun-JDK加密算法包加载到AIX(Java运行)环境中。 采用此方法。


第2种方法,在AIX上需要针对加密算法加载Sun-JDK/JRE的加密算法包

jre/lib/ext/sunjce_provider.jar、jre/lib/jce.jar下有SunJCE提供者(PBEWithSHA1AndDESede算法需要);jdk/lib/rt.jar下有SUN提供者(SHA-1算法需要) 


代码修改

显式加载加密算法提供者

[java] view plain copy
  1. static{  
  2.         if(null==Security.getProvider("SunJCE")){  
  3.             Security.addProvider(new com.sun.crypto.provider.SunJCE());  
  4.         }  
  5.           
  6.         if(null==Security.getProvider("SUN")){  
  7.             Security.addProvider(new sun.security.provider.Sun());  
  8.         }  
  9.     }  



加密算法使用时需要显式指出提供者名称

[java] view plain copy
  1. /** 
  2.      * 基于口令的加密方法 
  3.      * @param src 
  4.      * @return 
  5.      */  
  6.     public static   
  7.     byte[] encrypt(byte[] src){  
  8.         byte[] res = null;  
  9.           
  10.         try{  
  11.             PBEKeySpec keySpec = new PBEKeySpec(secretPasswd);    
  12.             SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithSHA1AndDESede""SunJCE");  //,"SunJCE"  
  13.             Key passwdKey = keyFactory.generateSecret(keySpec);              
  14.             PBEParameterSpec paramSpec = new PBEParameterSpec(secretSalt, secretIterations);  
  15.   
  16.             Cipher cip = Cipher.getInstance("PBEWithSHA1AndDESede""SunJCE");//, "SunJCE"  
  17.             cip.init(Cipher.ENCRYPT_MODE, passwdKey, paramSpec);  
  18.             //数据加密  
  19.             res = cip.doFinal(src);  
  20.         }catch(Exception ex){  
  21.             ex.printStackTrace();  
  22.         }  
  23.           
  24.         return res;  
  25.     }     

[java] view plain copy
  1. /** 
  2.  * 基于口令的解密方法 
  3.  * @param data 
  4.  * @return 
  5.  */  
  6. public static   
  7. byte[] decrypt(byte[] data){  
  8.     byte[] res = null;  
  9.       
  10.     try{  
  11.         PBEKeySpec keySpec = new PBEKeySpec(secretPasswd);    
  12.            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithSHA1AndDESede""SunJCE");  //,"SunJCE"  
  13.            Key passwdKey = keyFactory.generateSecret(keySpec);              
  14.            PBEParameterSpec paramSpec = new PBEParameterSpec(secretSalt, secretIterations);  
  15.   
  16.            Cipher cip = Cipher.getInstance("PBEWithSHA1AndDESede""SunJCE");//, "SunJCE"  
  17.            cip.init(Cipher.DECRYPT_MODE, passwdKey, paramSpec);  
  18.            //数据加密  
  19.            res = cip.doFinal(data);  
  20.     }catch(Exception ex){  
  21.         ex.printStackTrace();  
  22.     }  
  23.       
  24.     return res;  
  25. }  

[java] view plain copy
  1. /** 
  2.  * 返回16进制sha-1加密后信息 
  3.  * @param btInput 
  4.  * @return 
  5.  */  
  6. public static String sha1Hex(byte[] btInput){  
  7.     final char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};  
  8.     try {  
  9.         MessageDigest mdInst = MessageDigest.getInstance("SHA-1""SUN");  
  10.         mdInst.update(btInput);  
  11.         byte[] md = mdInst.digest();  
  12.         // 把密文转换成十六进制的字符串形式  
  13.            int j = md.length;  
  14.            char str[] = new char[j * 2];  
  15.              
  16.            for (int i=0,k=0; i < j; i++) {  
  17.                byte byte0 = md[i];  
  18.                str[k++] = hexDigits[byte0 >>> 4 & 0xf];  
  19.                str[k++] = hexDigits[byte0 & 0xf];  
  20.            }  
  21.              
  22.            return new String(str);              
  23.     } catch (Exception e) {  
  24.         e.printStackTrace();  
  25.         return "";  
  26.     }  
  27. }  

  1. Clear, inifamrtove, simple. Could I send you some e-hugs?