本来我们是只用了RSA加密原文的,后来发现原文太长,RSA只能加密117个字符,而且RSA加密的原文数据类型还需要区分是String还是JSONObject(可统称为Object),根据网上推荐的,我们选择了一种安全级别更高的加密方式,就是用AES加密原文,RSA公钥加密AES的秘钥,RSA私钥解密AES的秘钥,AES加密原文不用区分数据类型,统一转化为String类型就行,而且AES加密原文的长度没有限制,AES的秘钥比较短,就只有16位数字和大写字母的组合,不会超出RSA加密的长度。整个流程就是:A:随机生成AES的秘钥--》用AES秘钥加密原文--》用RSA公钥加密AES秘钥--》用RSA私钥签名原文;B:用RSA私钥解密AES秘钥--》用AES秘钥解密出原文--》用RSA公钥验证签名
AES加解密:
public class CryptAES { private static final String AESTYPE ="AES/ECB/PKCS5Padding"; public static String AES_Encrypt(String keyStr, String plainText) { byte[] encrypt = null; try{ Key key = generateKey(keyStr); Cipher cipher = Cipher.getInstance(AESTYPE); cipher.init(Cipher.ENCRYPT_MODE, key); encrypt = cipher.doFinal(plainText.getBytes()); }catch(Exception e){ e.printStackTrace(); } // return new String(Base64.encodeBase64(encrypt)); return new String(Base64.encodeToString(encrypt, Base64.DEFAULT)); } public static String AES_Decrypt(String keyStr, String encryptData) { byte[] decrypt = null; try{ Key key = generateKey(keyStr); Cipher cipher = Cipher.getInstance(AESTYPE); cipher.init(Cipher.DECRYPT_MODE, key); // decrypt = cipher.doFinal(Base64.decodeBase64(encryptData)); decrypt = cipher.doFinal(Base64.decode(encryptData, Base64.DEFAULT)); }catch(Exception e){ e.printStackTrace(); } return new String(decrypt).trim(); } private static Key generateKey(String key)throws Exception{ try{ SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES"); return keySpec; }catch(Exception e){ e.printStackTrace(); throw e; } } //随机生成AES加密秘钥 public static String getKey(){ Random random = new Random(); String result=""; for(int i=0;i<16;i++){ String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num"; //输出字母还是数字 if( "char".equalsIgnoreCase(charOrNum) ) { //输出是大写字母还是小写字母 // int temp = random.nextInt(2) % 2 == 0 ? 65 : 97; result += (char)(random.nextInt(26) + 65); } else if( "num".equalsIgnoreCase(charOrNum) ) { result += String.valueOf(random.nextInt(10)); } } return result; } }
RSA加解密和验签:
import android.util.Log; import org.json.JSONArray; import org.json.JSONObject; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.security.KeyFactory; 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 javax.crypto.Cipher; import Decoder.BASE64Decoder; import Decoder.BASE64Encoder; public class Rsa { // private String priKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKbVhyEl0dXL2Jew" + // "N9B8wQHaZ07nC5oSKpQR6sc7sdsoqS+G4h9zuFpBXlspOIpnvoWeSRckwX6icytC"+ // "uuqThOJaVhmiKV6w8zzyOvTVn0yaHMpXu9ZuhWFhx3xzDYy5rQfAAzKX1MO3k4ta"+ // "ZPTQLj8u7vaVEvbVq/FFO+YNCgCpAgMBAAECgYB1x4s1eJiyAc4wEITm2Bv+Lez/"+ // "BBfptmd+z0NbUiZW3VbLqcLbh3ufpERzwR8cfu8/L6bUAuvjddYutVZ2Ip0Nd7dG"+ //"5rrktH+7R8UT89fn87bUa5NlLee+egyoz/PJ63X4JjEg5OJbkXMbK4YrTypS0IAx"+ // "nZv+7BeSsCrzNlpWAQJBANgmHMDNrIWvU3qVf7u8SS/g+WrlvKMWOXtYjH2OqWoO"+ // "Vtmh4Or1PbaPIMnPAXFYiYYW8wcLYnVmVCez5qaysWkCQQDFl9XONZIMFAvdJ5S2"+ // "UFk63bEYtCroKZjddTlE6K/j+Vj2IaCFm94i4x1YzJR0KrykrtBTLRi7nuWmdJMJ"+ // "r61BAkA7dxDGAk+KX9fJi8Oe