0

我想在 Objective-C (iOS) 中加密一个字符串,并在 Java 中的 HTTP 传输之后对其进行解密。

公钥已成功从 Java 传输到 iOS(至少它在 Keychain 中被识别)

在 ObjC 中,我尝试使用以下命令发送文本“你好”:

NSData* myData = [@"Hallo" dataUsingEncoding:NSUTF8StringEncoding];
OSStatus status = noErr;    
size_t cipherBufferSize;
uint8_t *cipherBuffer;
cipherBufferSize = SecKeyGetBlockSize(publicKey);
cipherBuffer = malloc(cipherBufferSize);    
size_t dataLength = [self length];
uint8_t* intDataToEncrypt = (uint8_t*)[self bytes];
if (cipherBufferSize < dataLength) {
    printf("Could not encrypt.  Packet too large.\n");
    return NULL;
}
status = SecKeyEncrypt(    publicKey,
                       kSecPaddingNone,
                       intDataToEncrypt,
                       dataLength,
                       cipherBuffer,
                       &cipherBufferSize
                       );
NSData *encryptedData = [NSData dataWithBytes:cipherBuffer length:cipherBufferSize];

“encryptedData”然后通过 HTTP Post 将 base64 编码发送到使用它的 Java Servlet(使用 BouncyCastle 并首先从 Base64 转换回数据,从文件中读取密钥):

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(b64.decodeBuffer(key));
PrivateKey privateKey = kf.generatePrivate(keySpec);
Cipher cipher = Cipher.getInstance("RSA/NONE/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] myData = cipher.doFinal(byteData, 0, 256);

尝试使用 as new String(myData, "UTF-8"); 时,输出完全混乱;我尝试只发送“你好”而不加密,这行得通,所以看起来 base64 没问题。当我直接在 Java 中加密相同的短语时,输出与 ObjC 加密的 2 个字节不同。

最后我想使用 OAEP Padding 而不是 none...

我希望有人可以帮助解决这个问题,iOS 安全框架似乎真的很糟糕

4

1 回答 1

0

问题不在于 RSA 部分,而在于 Base64 编码和传输。由于 HTTP(S) 传输,字符串中的所有“+”都被接收为“”(当然,我应该想到这一点)。

按照非官方 Base64URL 版本的建议将它们替换为“-”可以解决问题。(还有所有带有“_”的“/”)

这也解释了为什么只有 2 个字节不同——那些是“+”符号字节。

于 2013-07-27T06:47:21.630 回答