Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/222.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PKCS1填充/RSA加密ios objc和java之间的差异_Java_Android_Ios_Encryption_Rsa - Fatal编程技术网

PKCS1填充/RSA加密ios objc和java之间的差异

PKCS1填充/RSA加密ios objc和java之间的差异,java,android,ios,encryption,rsa,Java,Android,Ios,Encryption,Rsa,我正在为ios和Android开发一个应用程序。我对加密任务还比较陌生,在过去的3天里,我一直把头撞在墙上,因为我无法运行RSA加密 两个客户端都从java服务器接收公钥。在安卓系统中,我没有遇到任何问题(很明显,因为它与服务器端的代码几乎相同),但ios部分似乎根本不兼容。我想用公钥加密一小段数据(aes密钥),我在Java中就是这样做的: 为了测试的目的和简单性,目前我只尝试加密一个长度为4字节的输入。这应该足够小,以适应一个块。公钥导入和加密过程似乎可以工作,但是与android方法相比

我正在为ios和Android开发一个应用程序。我对加密任务还比较陌生,在过去的3天里,我一直把头撞在墙上,因为我无法运行RSA加密

两个客户端都从java服务器接收公钥。在安卓系统中,我没有遇到任何问题(很明显,因为它与服务器端的代码几乎相同),但ios部分似乎根本不兼容。我想用公钥加密一小段数据(aes密钥),我在Java中就是这样做的:

为了测试的目的和简单性,目前我只尝试加密一个长度为4字节的输入。这应该足够小,以适应一个块。公钥导入和加密过程似乎可以工作,但是与android方法相比,我总是收到更长的输出


到目前为止,我遇到的唯一区别是,
SecKeyGetBlockSize返回16
,而在java cipher.blocksize中返回5。我认为其他11个字节是为pkcs1填充保留的,但是如何在
ios/objc
中强制执行相同的行为?

尝试将密码文本拆分为多个部分,以便每个部分包含16个字符,并分别对其进行解码。我也面临着同样的问题,但这在PHP中存在了很长一段时间,上面的技巧对我很有效


这可能有助于您解决此问题。

解码Base64密钥将提供:

MCwwDQYJKoZIhvcNAQEBBQADGwAwGAIRAK+dBpbOKw+1VKMWoFxjU6UCAwEAAQ==
-> 302c300d06092a864886f70d0101010500031b003018021100af9d0696ce2b0fb554a316a05c6353a50203010001
将其解释为DER编码ASN.1,我们发现:

30(2c) //SEQUENCE
  30(0d)  //SEQUENCE
    06(09): 2a 86 48 86 f7 0d 01 01 01  //OID 1.2.840.113548.1.1.1 (RSA Encryption)
    05(00): //NULL                           
    03(1b): [00] 30 18 02 11 00 af 9d 06 96 ce 2b 0f b5 54 a3 16 a0 5c 63 53 a5 02 03 01 00 01 //BITSTRING
其中,位字符串似乎还包含DER编码的ASN.1:

30(18) //SEQUENCE
  02(11): 00 af 9d 06 96 ce 2b 0f b5 54 a3 16 a0 5c 63 53 a5 02 03 01 00 01 //INTEGER

 = 0xaf9d0696ce2b0fb554a316a05c6353a50203010001
浏览IOS代码,您可以看到它正在解析DER编码的ASN.1。它正确识别前两个序列标记,并跳过OID字段,甚至不验证它是否为OID。然后问题就出现了:IOS代码希望下一个标记是 位字符串(0x03)——但是在我们的数据中,我们有一个额外的NULL(0x05)字段来表示公共指数是隐式的。IOS代码遇到0x05标记时引发异常。如果没有空值,我们可以看到IOS代码已经成功地提取了位字符串的内容

所以:要么NULL是一个可选字段,而IOS代码不允许它,要么IOS代码需要一个不同的ASN.1结构。例如,该位字符串似乎也是DER编码的ASN.1整数(可能是RSA模)。然而,IOS代码没有试图解析它。可能是IOS
SecKeyEncrypt
例程期望模数采用这种格式,也可能是调用者应该提取模数的原始字节

因此,仍然需要进行一些实验。但是,如果此代码要解析提供的数据对象,则以下附加条件肯定是必需的:

/* Skip OID */
i += 15;

if (i >= bytesLen - 2)
    [Exception raise:FAILURE function:__PRETTY_FUNCTION__ line:__LINE__ description:@"Could not set public key."];

if (bytes[i] == 0x05)    /* This should handle the spurious ASN.1 NULL field */
    i += 2;

if (bytes[i++] != 0x03)

在Android或Java中,生成的密钥是标准ASN.1格式,在外部世界(客户端、服务器端)运行良好,但在iOS中,生成的密钥(公共、私有)是原始格式,您必须将其转换为正确的ASN.1格式,以使其可用

你能用大一点的钥匙试试吗?128位的密钥有点小,一些加密库在512位以下的情况下不能很好地工作(我应该尝试1024位以确保)。你为什么要尝试一个在现实世界中没有用的钥匙尺寸?谢谢你的回答。我会提出建议,但我对服务器端代码不负责。你知道问题出在哪里了吗?我正面临类似的问题,如果您能提供任何帮助,我将不胜感激。您能告诉我,当从java服务器导入公钥时,密钥的格式是什么,这意味着我将获得public的.key扩展名文件(public.key)。。。它是加密的正确扩展吗
/* Skip OID */
i += 15;

if (i >= bytesLen - 2)
    [Exception raise:FAILURE function:__PRETTY_FUNCTION__ line:__LINE__ description:@"Could not set public key."];

if (bytes[i] == 0x05)    /* This should handle the spurious ASN.1 NULL field */
    i += 2;

if (bytes[i++] != 0x03)