【问题标题】:RSA ENCRYPTION IN ANDROID AND DECRYPTION IN SERVER SIDEAndroid 中的 RSA 加密和服务器端的解密
【发布时间】:2015-01-09 08:28:01
【问题描述】:

我已从 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中不起作用?

感谢您查看我的代码。

【问题讨论】:

  • 1) HTTPS 已经加密了所有内容。那么再次加密有什么意义。 2) PKCS#1v1.5 填充是不安全的。请改用 OAEP。
  • 第 1 点:https 对整个 url 字符串进行加密。但为了提高安全性,我们需要使用 ssl 加密,因此使用加密密码。这是每次身份验证中使用的常用方法。对于第2点:我已经知道因素。但是api是从客户端提供的。实际上oaep是PKCS#1v1.5填充的较新版本。无论如何感谢您的帮助。您可以帮助解决这个问题吗?
  • 您的代码以及您对 CodesInChaos 的评论都显示出对密码学的重大误解。也就是说,我认为你教 Codes 密码学是非常勇敢的。
  • 在移动端,我使用以下在线 rsa 计算器检查了我的加密,这似乎都是正确的(nmichaels.org/rsa.py).So 我认为移动端存在字节到十六进制转换的问题,而服务器端存在反向问题。我尊重codeInChaos,但我只是评论为什么我应该代表它的安全性遵循该方法。这里是android端的rsa加密和服务器端解密的问题。不是缺点或优点。

标签: java android encryption cryptography


【解决方案1】:

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

【讨论】:

  • 请注意,这个答案可能只能解决您的代码的直接问题,在我看来 CodesInChaos 是正确的。只是一个提示:看看使用挑战/响应的重放攻击和身份验证。
  • 实际上是移动端字节到十六进制转换和服务器端十六进制到字节转换的问题。上面的解密和加密部分是由另一个人实现的。我已经检查过UTF-8,base64和 org.apache.commons.codec.binary.Hex.encodeHex 编码方法,以标准化两端的转换。我无法获得肯定的响应。
  • 所以问题与编码有关。要么接受这个答案,要么指出它不正确的原因。如果您还有其他问题,请指出。
  • 应该是什么解决方案?我使用了不同的编码标准,但它们不会导致我得到积极的结果。我还在移动端测试了加密和解密,它们在移动端完美运行.
【解决方案2】:

感谢 Android 安全工程师 Alex Klyubin。我得到了Here的答复

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

代码注释:如果尚未安装,则默认安装基于 Linux PRNG 的 SecureRandom 实现。从 jellybean 开始就缺少此功能。

Sample code implementation

【讨论】:

    猜你喜欢
    • 2013-07-23
    • 2015-10-29
    • 1970-01-01
    • 2015-02-27
    • 2012-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多