繁体   English   中英

服务器端的Android加密和RSA加密

[英]RSA ENCRYPTION IN ANDROID AND DECRYPTION IN SERVER SIDE

我已经从Android向服务器发出了https api请求。 API请求包含一个参数,该参数在发送之前需要加密(即,它是密码)。 RSA/ECB/PKCS1Padding是两端使用的加密。

在android端加密执行以下操作:

/*Encrypt the password using public key.public key is obtained from generateRsaPublicKey(BigInteger modulus, BigInteger publicExponent) function)*/

public static String rsaEncrypt(String originalString, PublicKey key) {
    try {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] cipherByte = cipher.doFinal(original);
        return bytesToHex(cipherByte);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

//generate public key with given module and exponent value
public static PublicKey generateRsaPublicKey(BigInteger modulus, BigInteger publicExponent) {
    PublicKey key = null;
    try {
        key = KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(modulus, publicExponent));
      return key;
    } catch (Exception e) {
        Log.e("error", e.toString());
        // return null;
    }
    return key;
}

// Helper methods

final protected static char[] hexArray = "0123456789abcdef".toCharArray();
public static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    for ( int j = 0; j < bytes.length; j++ ) {
        int v = bytes[j] & 0xFF;
       // Log.d("byte array representaion","value in integrer"+v);
        hexChars[j * 2] = hexArray[v >>> 4];           
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}

以下是解密服务器上密码的来源

// *** setup private key

RSAPrivateKeySpec privateRPKS
= new RSAPrivateKeySpec(new BigInteger(gModulusPlainS, 16), new BigInteger(privateExponentPlainS, 16));
KeyFactory keyFactoryKF = KeyFactory.getInstance("RSA");
RSAPrivateKey gPrivateKeyRPK = (RSAPrivateKey) keyFactoryKF.generatePrivate(privateRPKS);

// *** setup cipher
Cipher cipherC = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipherC.init(Cipher.DECRYPT_MODE, gPrivateKeyRPK);

// *** decrypt hex-encoded cipherTxS
byte[] baCipherText = hexToBin(cipherTxS.getBytes());
byte[] baPlainText2 = cipherC.doFinal(baCipherText);
String decryptedTextS = new String(baPlainText2);

但是我得到了以下错误日志

javax.crypto.IllegalBlockSizeException: Data size too large
    at com.ibm.crypto.provider.RSASSL.a(Unknown Source)
    at com.ibm.crypto.provider.RSASSL.engineDoFinal(Unknown Source)
    at javax.crypto.Cipher.doFinal(Unknown Source)

javax.crypto.BadPaddingException: Not PKCS#1 block type 2 or Zero padding

但是它正在Websight部分上工作。 为什么它在Android中不起作用?

感谢您对我的代码的关注。

如果cipherTxS.getBytes()确实是字符串到字节数组的转换,则将密文作为字符串发送。 密文应保留为二进制或可能使用base 64编码进行编码。

感谢Android安全工程师Alex Klyubin。 我从这里得到答案

使用JCA进行密钥生成,签名或随机数生成的开发人员应更新其应用程序,以使用/ dev / urandom或/ dev / random中的熵显式初始化PRNG。此外,开发人员应评估是否先前重新生成加密密钥或其他随机值使用诸如SecureRandom,KeyGenerator,KeyPairGenerator,KeyAgreement和Signature之类的JCA API生成的。

代码注释:如果尚未安装,则默认安装基于Linux PRNG的SecureRandom实现。

示例代码实现

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM