packagecom.cn.test.rsa;importjava.math.BigInteger;importjava.security.KeyFactory;importjava.security.KeyPair;importjava.security.KeyPairGenerator;importjava.security.NoSuchAlgorithmException;importjava.security.interfaces.RSAPrivateKey;importjava.security.interfaces.RSAPublicKey;importjava.security.spec.RSAPrivateKeySpec;importjava.security.spec.RSAPublicKeySpec;importjava.util.HashMap;importjavax.crypto.Cipher;public classRSAUtils {/*** 生成公钥和私钥
*@throwsNoSuchAlgorithmException
**/
public static HashMap getKeys() throwsNoSuchAlgorithmException{
HashMap map = new HashMap();
KeyPairGenerator keyPairGen= KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(1024);
KeyPair keyPair=keyPairGen.generateKeyPair();
RSAPublicKey publicKey=(RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey=(RSAPrivateKey) keyPair.getPrivate();
map.put("public", publicKey);
map.put("private", privateKey);returnmap;
}/*** 使用模和指数生成RSA公钥
* 注意:【此代码用了默认补位方式,为RSA/None/PKCS1Padding,不同JDK默认的补位方式可能不同,如Android默认是RSA
* /None/NoPadding】
*
*@parammodulus
* 模
*@paramexponent
* 指数
*@return
*/
public staticRSAPublicKey getPublicKey(String modulus, String exponent) {try{
BigInteger b1= newBigInteger(modulus);
BigInteger b2= newBigInteger(exponent);
KeyFactory keyFactory= KeyFactory.getInstance("RSA");
RSAPublicKeySpec keySpec= newRSAPublicKeySpec(b1, b2);return(RSAPublicKey) keyFactory.generatePublic(keySpec);
}catch(Exception e) {
e.printStackTrace();return null;
}
}/*** 使用模和指数生成RSA私钥
* 注意:【此代码用了默认补位方式,为RSA/None/PKCS1Padding,不同JDK默认的补位方式可能不同,如Android默认是RSA
* /None/NoPadding】
*
*@parammodulus
* 模
*@paramexponent
* 指数
*@return
*/
public staticRSAPrivateKey getPrivateKey(String modulus, String exponent) {try{
BigInteger b1= newBigInteger(modulus);
BigInteger b2= newBigInteger(exponent);
KeyFactory keyFactory= KeyFactory.getInstance("RSA");
RSAPrivateKeySpec keySpec= newRSAPrivateKeySpec(b1, b2);return(RSAPrivateKey) keyFactory.generatePrivate(keySpec);
}catch(Exception e) {
e.printStackTrace();return null;
}
}/*** 公钥加密
*
*@paramdata
*@parampublicKey
*@return*@throwsException*/
public staticString encryptByPublicKey(String data, RSAPublicKey publicKey)throwsException {
Cipher cipher= Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);//模长
int key_len = publicKey.getModulus().bitLength() / 8;//加密数据长度 <= 模长-11
String[] datas = splitString(data, key_len - 11);
String mi= "";//如果明文长度大于模长-11则要分组加密
for(String s : datas) {
mi+=bcd2Str(cipher.doFinal(s.getBytes()));
}returnmi;
}/*** 私钥解密
*
*@paramdata
*@paramprivateKey
*@return*@throwsException*/
public staticString decryptByPrivateKey(String data, RSAPrivateKey privateKey)throwsException {
Cipher cipher= Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);//模长
int key_len = privateKey.getModulus().bitLength() / 8;byte[] bytes =data.getBytes();byte[] bcd =ASCII_To_BCD(bytes, bytes.length);
System.err.println(bcd.length);//如果密文长度大于模长则要分组解密
String ming = "";byte[][] arrays =splitArray(bcd, key_len);for(byte[] arr : arrays){
ming+= newString(cipher.doFinal(arr));
}returnming;
}/*** ASCII码转BCD码
**/
public static byte[] ASCII_To_BCD(byte[] ascii, intasc_len) {byte[] bcd = new byte[asc_len / 2];int j = 0;for (int i = 0; i < (asc_len + 1) / 2; i++) {
bcd[i]= asc_to_bcd(ascii[j++]);
bcd[i]= (byte) (((j >= asc_len) ? 0x00 : asc_to_bcd(ascii[j++])) + (bcd[i] << 4));
}returnbcd;
}public static byte asc_to_bcd(byteasc) {bytebcd;if ((asc >= '0') && (asc <= '9'))
bcd= (byte) (asc - '0');else if ((asc >= 'A') && (asc <= 'F'))
bcd= (byte) (asc - 'A' + 10);else if ((asc >= 'a') && (asc <= 'f'))
bcd= (byte) (asc - 'a' + 10);elsebcd= (byte) (asc - 48);returnbcd;
}/*** BCD转字符串*/
public static String bcd2Str(byte[] bytes) {char temp[] = new char[bytes.length * 2], val;for (int i = 0; i < bytes.length; i++) {
val= (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);
temp[i* 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
val= (char) (bytes[i] & 0x0f);
temp[i* 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
}return newString(temp);
}/*** 拆分字符串*/
public static String[] splitString(String string, intlen) {int x = string.length() /len;int y = string.length() %len;int z = 0;if (y != 0) {
z= 1;
}
String[] strings= new String[x +z];
String str= "";for (int i=0; i
str= string.substring(i*len, i*len+y);
}else{
str= string.substring(i*len, i*len+len);
}
strings[i]=str;
}returnstrings;
}/***拆分数组*/
public static byte[][] splitArray(byte[] data,intlen){int x = data.length /len;int y = data.length %len;int z = 0;if(y!=0){
z= 1;
}byte[][] arrays = new byte[x+z][];byte[] arr;for(int i=0; i
arr= new byte[len];if(i==x+z-1 && y!=0){
System.arraycopy(data, i*len, arr, 0, y);
}else{
System.arraycopy(data, i*len, arr, 0, len);
}
arrays[i]=arr;
}returnarrays;
}
}