Android RSA加密

和小段讨论之后,我觉得现在APP加密还是比较严峻的,一个是APP本身被破击打包,还有一个是接口被利用。

本文主要是想通过加密的方式来防止接口被直接抓包抓到,虽然依旧可破解,但是能让破解者费点力气。

生成密钥

RSA加密的密钥有两种,一种是公钥,另一种是私钥,公钥是用来加密的,密钥用于解密。在实际应用中,将公钥给Android客户端,Android客户端提交数据通过这个公钥加密后上传到服务器,服务器用私钥来解密。上报的时候使用post方法,然后将数据包装成Json的格式加密。服务器端解析之后也比较方便使用。

  • JAVA的生产key的代码

    KeyPairGenerator kpg;
        try {
        kpg = KeyPairGenerator.getInstance("RSA");
        // 创建‘密匙对’生成器
        kpg.initialize(512); // 指定密匙长度(取值范围:512~2048)
        KeyPair kp = kpg.genKeyPair(); // 生成‘密匙对’,其中包含着一个公匙和一个私匙的信息
        PublicKey public_key = kp.getPublic(); // 获得公匙
        PrivateKey private_key = kp.getPrivate(); // 获得私匙
    
        BASE64Encoder b64 = new BASE64Encoder();
        String pkStr = b64.encode(public_key.getEncoded());
        String prStr = b64.encode(private_key.getEncoded());
    
        System.out.println("public key is " + pkStr);
        System.out.println("*****************");
        System.out.println("private key is " + prStr);
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    

需要说明的是,BASE64Encoder在Android直接自带Base64类,生产的key转为Base64

  • 另一种方式生产RSA的key
    使用openssl的方式生成

生成密钥 密钥的长度512-2048

openssl genrsa -out privateKey.pem 1024   

生成公钥

openssl rsa -in privateKey.pem -out publicKey.pem -pubout

公钥需要提供私钥来生成

生成的私钥没法直接使用需要使用pkcs8转码
所以还需要输入指令

openssl pkcs8 -topk8 -in privateKey.pem -out pk8_private.pem -nocrypt

指令解释:-in表示输入的pem文件,-out表示输出的文件名,-nocrypt表示无视版权。

加密

加密是通过公钥来加密的
代码如下

    try {
        byte[] keyByte = Base64.decode(newPublic, Base64.DEFAULT);
        X509EncodedKeySpec x509ek = new X509EncodedKeySpec(keyByte);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509ek);

        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] sbt = source.getBytes();
        byte[] epByte = cipher.doFinal(sbt);
        byte[] epStr = Base64.encode(epByte, Base64.DEFAULT);
        afterDecoder = new String(epStr);
        System.out.println("after decode is " + new String(epStr));
    } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException
            | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
        e.printStackTrace();
    }

解密

解密需要用到密钥
代码如下

try {
        byte[] keyByte = Base64.decode(newPrivate, Base64.DEFAULT);

        PKCS8EncodedKeySpec s8ek = new PKCS8EncodedKeySpec(keyByte);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(s8ek);

        /** 得到Cipher对象对已用公钥加密的数据进行RSA解密 */
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] b1 = Base64.decode(afterDecoder, Base64.DEFAULT);
        /** 执行解密操作 */
        byte[] b = cipher.doFinal(b1);
        System.out.println("decoder result is " + new String(b));
    } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
RSA封装类 ,完整的RSA加密和解密 public class RSAUtilEncrypt { public static final String KEY_ALGORTHM = "RSA";// public static final String KEY_ALGORTHM_RSA_ECB_PKCS1PADDING = "RSA/ECB/PKCS1Padding"; public static String RSA_PUBLIC_KEY = "rsa_public_key"; public static String RSA_PRIVATE_KEY = "rsa_private_key"; private int KeySize = 1024; private Map keyMap; private static String RSA = "RSA"; private static PublicKey publickey; public RSAUtilEncrypt(int KeySize,String publickey) { this.KeySize = KeySize; try { this.publickey=generatePublicKeyByString(publickey); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } private RSAPublicKey generatePublicKeyByString(String publicKeyStr) throws Exception { try { BASE64Decoder base64Decoder = new BASE64Decoder(); byte[] buffer = base64Decoder.decodeBuffer(publicKeyStr); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return (RSAPublicKey) keyFactory.generatePublic(keySpec); } catch (NoSuchAlgorithmException e) { throw new Exception("No Algorthm,Checked by cemung!"); } catch (InvalidKeySpecException e) { throw new Exception("InvalidKeySpec!"); } catch (IOException e) { throw new Exception("Io exception!"); } catch (NullPointerException e) { throw new Exception("Illegle pointer reference!"); } } // Encypt public byte[] RSAEncrypt(byte[] data, RSAPublicKey publickey) throws Exception { Cipher cipher = Cipher.getInstance(KEY_ALGORTHM_RSA_ECB_PKCS1PADDING); cipher.init(Cipher.ENCRYPT_MODE, this.publickey); byte[] cipherbytes = cipher.doFinal(data); return cipherbytes; } // Encypt public byte[] RSAEncrypt(byte[] data) throws Exception { Cipher cipher = Cipher.getInstance(KEY_ALGORTHM_RSA_ECB_PKCS1PADDING); cipher.init(Cipher.ENCRYPT_MODE, this.publickey); byte[] cipherbytes = cipher.doFinal(data); return cipherbytes; } // Get Public key with format byte[] public byte[] getPublicKeyByte() { RSAPublicKey pubkey = (RSAPublicKey) keyMap.get(RSA_PUBLIC_KEY); return pubkey.getEncoded(); } public static byte[] decryptBASE64(String key) throws Exception { return (new BASE64Decoder()).decodeBuffer(key); } public static String encryptBASE64(byte[] key) throws Exception { return (new BASE64Encoder()).encodeBuffer(key); } public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception { byte[] keyBytes = decryptBASE64(key); PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec( keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM); Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception { byte[] keyBytes = decryptBASE64(key); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM); Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data); } public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception { byte[] keyBytes = decryptBASE64(key); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM); Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } 使用方法 private RSAUtilEncrypt rsa = new RSAUtilEncrypt(1024, publikey); /* * 给信息加密,获取密文 */ public String getCiphertext(String str_encrode) { try { byte[] estr = rsa.RSAEncrypt(str_encrode.getBytes()); // 密文 String ciphertext = Base64.encodeToString(estr, Base64.DEFAULT); return ciphertext; } catch (Exception e) { e.printStackTrace(); } return null; } 有疑问的留言
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值