gpt4 book ai didi

java - RSA Ruby 和 Android 填充问题

转载 作者:行者123 更新时间:2023-11-30 00:21:54 24 4
gpt4 key购买 nike

填充问题

1) 我正在使用带 PKCS1_PADDING 的公钥在 ruby​​ 中加密消息。

2) 然后将输出(ASCII-8BIT 编码)转换为十六进制并将其发送到 android 设备。

3) 在 android 上将十六进制转换为字节数组并使用私钥对其进行解密,我得到了很多额外的字符。 (在 android 端,它默认为 RSA/NONE/PKCS1Padding)。

例子:

预期字符串:你好,你好吗?

实际字符串:V')f�rBA�;\�:�D�.a�~�A@�.P�(�l�-�ך��\�0}�nj. F�@Ƨ�Wr[�k�Ez�o���r����K����1D���U!�t�.UI?�gA ��|X��o@v��K��Ə������'��n�F������ P��0��9m9*u��٘S��1������<>��L��?��;3����~��-)$������ *“����%/Oѡ��k@��你好,你好吗?

Java代码:

public String Decrypt (String result,String privKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
{
PrivateKey privateKey = getPrivateKeyFromString(privKey);
Cipher cipher1 = Cipher.getInstance("RSA");
cipher1.init(Cipher.DECRYPT_MODE, privateKey);
String decrypted="";
try {
byte[] bytes = hexStringToByteArray(result);
byte[] decryptedBytes = cipher1.doFinal(bytes);
decrypted = new String(decryptedBytes);
}catch (Exception e)
{
e.printStackTrace();
}
return decrypted;

}

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

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;
}

ruby 代码:

 require 'openssl'
require 'base64'

public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn6fT8ScFrW2FR5bxTeFzsD77nN1W+gL5XUB1yQVNL699y6WISopbQ6lls76XvKfyhJHn7ca8i5rDRXrNnaY1BVvX9n/jKWLw13AQcVG4SjMewMQbW1KXOWFe2cltGxB7dX+4xlnxRtXz26xtOpEoBdMN2LBB39WdMghaLIrzcNu9uj363KK8szs9x9rO9E5BNfaqePFwajJoOXjkc5PUwRHeW2DodQnKfxJhaBwotoBbD6zrx+XPqpEzXD7XLjq2i/MGEuw6XGLCGQ+/zaytiYCDe8gboQ5WkWQtfa0FALve9zguqjpoNouWaK4SBq1kyeFKsdsbmZLC8NdJlSruUQIDAQAB"

rsa_public_key = OpenSSL::PKey::RSA.new(Base64.decode64(public_key))

encrypted_string = rsa_public_key.public_encrypt('hello how are you doing ?', OpenSSL::PKey::RSA::PKCS1_PADDING)

encrypted_string.unpack("H*")

最佳答案

为了获得最大的可移植性,您应该使用 "RSA/ECB/PKCS1Padding" 作为密码的初始化字符串。

这个字符串实际上已经在Java Standard Algorithm Names中定义了根据任何 Java 实现的要求。当然,Android 还不是正式的 Java,但您可以肯定 Google 会尝试并确保它尽可能接近 Java。所以这应该与任何 Java(-ish)实现兼容。

Sun 要求的是操作模式(上面字符串中的"ECB")和填充方案("PKCS1Padding") 是 "RSA" 的默认值。这就是为什么你必须明确指定那些。永远不要依赖提供者特定的默认值 - 指定随机数生成器时除外。

您目前得到的是 "RSA/ECB/NoPadding" 方案,它使所有填充保持不变。因此,当您查看以字节为单位的明文大小时,它将与模数的以字节为单位的大小相同。内容将是 PKCS#1-padding,它(大部分)对于每次加密都是随机的。随机字节不能轻易转换为文本,因此您返回的内容主要看起来像垃圾。


注意事项:

  • "ECB" 是 Sun 的用词不当,它应该是 "None" 因为只能加密一个明文 block (通常);
  • 即使 Android 默认使用 UTF-8(Windows 上的 Java 使用 Windows-1252 编码!),您也应该在将字节转换为字符串时明确指定字符集;
  • 最好的随机数生成通常是特定于平台的,因此使用特定算法实际上可能会降低实现的安全性,对于定义不正确的 “SHA1PRNG” 更是如此。

关于java - RSA Ruby 和 Android 填充问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46137057/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com