【问题标题】:Encryption compatibility between SJCL and java Bouncy Castle RSASJCL 和 java Bouncy Castle RSA 之间的加密兼容性
【发布时间】:2014-03-21 19:08:41
【问题描述】:

我正在开发一个使用 RSA 加密的 android 应用程序。

我可以从我的服务器获取我的私钥和我朋友的公钥。

私钥是这样的:

{"n":"...","d":"...","p":"...","q":"...","dmp1":"...","dmq1":"...","coeff":"..."} (jsbn json format)

modulus => n
public exponent => e
private exponent => d
prime1 => p
prime2 => q
exponent1 => dmp1
exponent2 => dmq1
coefficient => coeff

使用此密钥,我需要解密从我的服务器接收并已由 javascript 库 (SJCL) 加密的消息。 我还需要对消息进行加密,以便能够使用 javascrypt 库对其进行解密。

现在我已经这样做了:

 public static String decrypt (String data, String stringKey) throws Exception {
        JSONObject jsonKey = new JSONObject(stringKey);

        BigInteger n = new BigInteger(Base64.decode(jsonKey.getString("n"), Base64.DEFAULT));
        BigInteger e = new BigInteger("10001");
        BigInteger d = new BigInteger(Base64.decode(jsonKey.getString("d"), Base64.DEFAULT));
        BigInteger p = new BigInteger(Base64.decode(jsonKey.getString("p"), Base64.DEFAULT));
        BigInteger q = new BigInteger(Base64.decode(jsonKey.getString("q"), Base64.DEFAULT));
        BigInteger dmp1 = new BigInteger(Base64.decode(jsonKey.getString("dmp1"), Base64.DEFAULT));
        BigInteger dmq1 = new BigInteger(Base64.decode(jsonKey.getString("dmq1"), Base64.DEFAULT));
        BigInteger coeff = new BigInteger(Base64.decode(jsonKey.getString("coeff"), Base64.DEFAULT));


        KeySpec privateKeySpec = new RSAPrivateCrtKeySpec(n, e, d, p, q, dmp1, dmq1, coeff);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);

        Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] dec = cipher.doFinal(data.getBytes());
        return new String(Base64.decode(dec, Base64.DEFAULT));
    }

现在我明白了:

javax.crypto.IllegalBlockSizeException: 输入必须小于 96 字节

【问题讨论】:

  • 数据长度是多少?
  • 还要注意BigInteger e = new BigInteger("10001", 16);

标签: javascript android rsa sjcl jsbn


【解决方案1】:

PrivateKey.getEncoded() 用于 RSA 私钥返回根据 PKCS#1 标准编码的 ASN.1 二进制。

【讨论】:

  • 根据 SJCL 库,我正在寻找使用此 json 的方法来获取真正的私钥。
  • 这是否意味着您的问题与 BouncyCastle 没有任何关系?
  • 如果可以的话,我想使用充气城堡库。但我的主要问题与我在 java 中使用 SJCL 输出的方式有关
  • 你肯定需要澄清你的问题,它非常模糊。
【解决方案2】:

在另一个项目上花费了大量时间后,我重新使用了这个应用程序,并解决了我的问题。

首先,SJCL/JSBN库生成的私钥json是hexa字符串。 所以我只需要将我的字符串转换为字节数组。

BigInteger n = new BigInteger(Utils.hexStringToByteArray(nString));
BigInteger e = new BigInteger("10001", 16); // Public exponent

发送的加密数据,也是一个十六进制字符串。

byte[] dec = cipher.doFinal(Utils.hexStringToByteArray(data));
return new String(dec, "UTF-8");

密码返回一个字节数组作为明文。

算法如下:

Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");

还有 hexStringToByteArray 函数:

public static byte[] hexStringToByteArray(String s) {
  int len = s.length();
  byte[] data = new byte[len/2];

  s = s.toUpperCase();
  for(int i = 0; i < len; i+=2){
    data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
  }

 return data;
}

public static String byteArrayToHexString(byte[] bytes) {
  char[] hexChars = new char[bytes.length*2];
  int v;

  for(int j=0; j < bytes.length; j++) {
    v = bytes[j] & 0xFF;
    hexChars[j*2] = hexArray[v>>>4];
    hexChars[j*2 + 1] = hexArray[v & 0x0F];
  }

  return new String(hexChars).toLowerCase();
}

当时我看错了地方,将我的 BigInteger 解码为 base64 编码字符串。

【讨论】:

    猜你喜欢
    • 2015-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 2012-04-25
    • 2018-05-20
    • 2011-01-26
    • 2013-02-20
    相关资源
    最近更新 更多