本来我们是只用了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+KX9fJi8OedIh2AaDcxeOFwqGBy7Sq/kqhgNxn918XhOy7gtj0"+ // "bFzrP/5lw36M25b00XgpjBbSmaqxAkBnBN/TUHjh1T3OQ0m0uDWdjGI+KAlK3A04"+ // "QVrng43ZBXMNeMDRiE+Lzu/JEXjBDFsoXYB+LT/86j5/x721yiNBAkEAgi0F5BvA"+ // "wYZQXqAx3iyuj8R9uUKpLePafyBRHnLNrFux2VD0ZX3pXCmfDDmtM/NMO491dI84"+ //"6NbVOvxWcNPQ/Q=="; //private String pubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCm1YchJdHVy9iXsDfQfMEB2mdO"+ //"5wuaEiqUEerHO7HbKKkvhuIfc7haQV5bKTiKZ76FnkkXJMF+onMrQrrqk4TiWlYZ"+ // "oilesPM88jr01Z9MmhzKV7vWboVhYcd8cw2Mua0HwAMyl9TDt5OLWmT00C4/Lu72"+ // "lRL21avxRTvmDQoAqQIDAQAB"; ; public Rsa(){ // priKey = readStringFromFile("java_private.pem"); // pubKey = readStringFromFile("java_public.pem"); } /** * 使用私钥加密 * */ public String encryptByPrivateKey(String data) { // 加密 String str = ""; try { byte[] pribyte = base64decode(priKey.trim()); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte); KeyFactory fac = KeyFactory.getInstance("RSA"); RSAPrivateKey privateKey = (RSAPrivateKey) fac.generatePrivate(keySpec); Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding"); c1.init(Cipher.ENCRYPT_MODE, privateKey); str = base64encode(c1.doFinal(data.getBytes())); } catch (Exception e) { e.printStackTrace(); } return str; } /** * 使用私钥解密 * */ public String decryptByPrivateKey(String data) { // 加密 String str = ""; try { byte[] pribyte = base64decode(priKey.trim()); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte); KeyFactory fac = KeyFactory.getInstance("RSA"); RSAPrivateKey privateKey = (RSAPrivateKey) fac.generatePrivate(keySpec); Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding"); c1.init(Cipher.DECRYPT_MODE, privateKey); byte[] temp = c1.doFinal(base64decode(data)); str = new String(temp); } catch (Exception e) { e.printStackTrace(); } return str; } //数组解密 public String[] decryptByPrivateKey1(String data) { // 加密 String[] str = {}; try { byte[] pribyte = base64decode(priKey.trim()); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte); KeyFactory fac = KeyFactory.getInstance("RSA"); RSAPrivateKey privateKey = (RSAPrivateKey) fac.generatePrivate(keySpec); Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding"); c1.init(Cipher.DECRYPT_MODE, privateKey); byte[] temp = c1.doFinal(base64decode(data)); try { //object to bytearray ByteArrayInputStream bo = new ByteArrayInputStream(temp); ObjectInputStream oo = new ObjectInputStream(bo); Object object = oo.readObject(); str = (String[]) object; // bytes = bo.toByteArray(); bo.close(); oo.close(); } catch(Exception e) { System.out.println("translation"+e.getMessage()); e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); } return str; } /** * 使用公钥加密 * */ public String encryptByPublicKey(String data) { // 加密 String str = ""; try { byte[] pubbyte = base64decode(pubKey.trim()); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte); KeyFactory fac = KeyFactory.getInstance("RSA"); RSAPublicKey rsaPubKey = (RSAPublicKey) fac.generatePublic(keySpec); Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding"); c1.init(Cipher.ENCRYPT_MODE, rsaPubKey); str = base64encode(c1.doFinal(data.getBytes())); } catch (Exception e) { e.printStackTrace(); } return str; } public String encryptByPublicKey1(JSONObject data) { // 加密 String str = ""; try { byte[] pubbyte = base64decode(pubKey.trim()); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte); KeyFactory fac = KeyFactory.getInstance("RSA"); RSAPublicKey rsaPubKey = (RSAPublicKey) fac.generatePublic(keySpec); Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding"); c1.init(Cipher.ENCRYPT_MODE, rsaPubKey); byte[] bytes; try { //object to bytearray ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(bo); oo.writeObject(data); str = base64encode(c1.doFinal(bo.toByteArray())); // bytes = bo.toByteArray(); bo.close(); oo.close(); } catch(Exception e) { System.out.println("translation"+e.getMessage()); e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); } return str; } /** * 使用公钥解密 * */ public String decryptByPublicKey(String data) { // 加密 String str = ""; try { byte[] pubbyte = base64decode(pubKey.trim()); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte); KeyFactory fac = KeyFactory.getInstance("RSA"); RSAPublicKey rsaPubKey = (RSAPublicKey) fac.generatePublic(keySpec); Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding"); c1.init(Cipher.DECRYPT_MODE, rsaPubKey); byte[] temp = c1.doFinal(base64decode(data)); str = new String(temp); } catch (Exception e) { e.printStackTrace(); } return str; } /** * 本方法使用SHA1withRSA签名算法产生签名 * @param src 签名的原字符串 * @return String 签名的返回结果(16进制编码)。当产生签名出错的时候,返回null。 */ public String signByPrivateKey(String src) { try { Signature sigEng = Signature.getInstance("SHA1withRSA"); byte[] pribyte = base64decode(priKey.trim()); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte); KeyFactory fac = KeyFactory.getInstance("RSA"); RSAPrivateKey privateKey = (RSAPrivateKey) fac.generatePrivate(keySpec); sigEng.initSign(privateKey); sigEng.update(src.getBytes()); byte[] signature = sigEng.sign(); return base64encode(signature); } catch (Exception e) { e.printStackTrace(); return null; } } public String signByPrivateKey1(JSONArray data) { try { Signature sigEng = Signature.getInstance("SHA1withRSA"); byte[] pribyte = base64decode(priKey.trim()); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte); KeyFactory fac = KeyFactory.getInstance("RSA"); RSAPrivateKey privateKey = (RSAPrivateKey) fac.generatePrivate(keySpec); sigEng.initSign(privateKey); byte[] bytes; try { //object to bytearray ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(bo); oo.writeObject(data); bytes = bo.toByteArray(); sigEng.update(bytes); bo.close(); oo.close(); } catch(Exception e) { System.out.println("translation"+e.getMessage()); Log.i("wanlijun",e.toString()); e.printStackTrace(); } byte[] signature = sigEng.sign(); return base64encode(signature); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 使用共钥验证签名 * @param sign * @param src * @return */ public boolean verifyByPublicKey(String sign, String src) { try { Signature sigEng = Signature.getInstance("SHA1withRSA"); byte[] pubbyte = base64decode(pubKey.trim()); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte); KeyFactory fac = KeyFactory.getInstance("RSA"); RSAPublicKey rsaPubKey = (RSAPublicKey) fac.generatePublic(keySpec); sigEng.initVerify(rsaPubKey); sigEng.update(src.getBytes()); byte[] sign1 = base64decode(sign); return sigEng.verify(sign1); } catch (Exception e) { e.printStackTrace(); return false; } } /** * base64加密 * @param bstr * @return */ @SuppressWarnings("restriction") private String base64encode(byte[] bstr) { String str = new BASE64Encoder().encode(bstr); str = str.replaceAll("\r\n", "").replaceAll("\r", "").replaceAll("\n", ""); return str; } /** * base64解密 * @param str * @return byte[] */ @SuppressWarnings("restriction") private byte[] base64decode(String str) { byte[] bt = null; try { BASE64Decoder decoder = new BASE64Decoder(); bt = decoder.decodeBuffer(str); } catch (IOException e) { e.printStackTrace(); } return bt; } /** * 从文件中读取所有字符串 * @param fileName * @return String */ private String readStringFromFile(String fileName){ StringBuffer str = new StringBuffer(); try { File file = new File(fileName); FileReader fr = new FileReader(file); char[] temp = new char[1024]; while (fr.read(temp) != -1) { str.append(temp); } fr.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return str.toString(); } }
使用:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_rsa); Rsa rsa = new Rsa(); //随机生成AES加密数据的秘钥 String keyStr = CryptAES.getKey(); Log.i("wanlijun","秘钥:"+keyStr); String sign2 = "loONhbEu/y1/yjouOI4Hi9l11IqWoZAZSvn4r18WpjIzlMWaoPaKWbr+RjzPtzKbUfaM6pyRSZPs09h75BX+DZwoC60Ja6qk6AT1qIXzBg47uACezXc4mMLf1gfm6xHO/9LdMvjpLMCuIno6srvs8CAKdYsfINObOrVSi2jP+lw="; String src2 = "[{\"money\":500,\"timelimt\":15,\"purpose\":1,\"name\":\"\\u9ad8\\u7ea7\",\"age\":23}]"; //RSA验证签名 boolean sign3 = rsa.verifyByPublicKey(sign2,src2); Log.i("wanlijun","sign3:"+sign3); //RSA签名 String sign4 = rsa.signByPrivateKey("123456"); Log.i("wanlijun","sign4:"+sign4); //RSA公钥加密 String sign7 = rsa.encryptByPublicKey("123456"); Log.i("wanlijun","sign7:"+sign7); //RSA私钥验证 String sign8 = rsa.decryptByPrivateKey(sign7); Log.i("wanlijun","sign8:"+sign8); String[][] str2 = {{"money = 1000","name=\"高级\""},{"money = 1000","sex=\"女\""},{"age = 26","name=\"哈哈\""},{"errorCode = 0","likelihood = 1"},{"errorCode = 0","likelihood = 1"},{"errorCode = 0","likelihood = 1"}}; //将二位数组转化为JSONArray类型的字符串 StringBuffer sb2 = new StringBuffer(); sb2.append("["); for(int i =0;i<str2.length;i++){ String[] temp = str2[i]; if(i != 0){ sb2.append(","); } sb2.append("{"); for(int j = 0;j<temp.length;j++){ String temp2 = temp[j]; String[] ary = temp2.split("="); if(ary.length > 1){ if(j != 0){ sb2.append(","); } sb2.append("\""+ary[0].trim()+"\""); sb2.append(":"); sb2.append(ary[1].trim()); } } sb2.append("}"); } sb2.append("]"); Log.i("wanlijun","原文:"+sb2.toString()); String crypt = CryptAES.AES_Encrypt(keyStr,sb2.toString()); Log.i("wanlijun","AES加密后的密文:"+crypt); String key = rsa.encryptByPublicKey(keyStr); Log.i("wanlijun","RSA加密AES的秘钥:"+key); //RSA私钥签名原文 String sign = rsa.signByPrivateKey(sb2.toString());
StringBuffer sb = new StringBuffer(); sb.append("{"); try { for(int i =0;i<str.length;i++){ String temp = str[i]; Log.i("wanlijun","公钥加密密文:"+temp); String[] ary = temp.split("="); if(ary.length > 1){ if(i != 0){ sb.append(","); } sb.append("\""+ary[0].trim()+"\""); sb.append(":"); sb.append(ary[1].trim()); } } sb.append("}");
}