ios rsa加密 java解密_RSA:在iOS中加密,在Java中解密

我有一个从Java服务器发送的公钥。在我解码并去除ASN.1标头之前,base64编码的字符串匹配。我使用将公钥存储在钥匙串中SecItemAdd。

因此,我尝试使用公共密钥对数据进行加密,并使用Java中的私有密钥对其进行解密。我SecKeyEncrypt在iOS端和CipherJava端使用。

我正在加密的是对称AES密钥,该密钥对我的实际数据进行加密,因此密钥长度为16个字节。当简单地对密钥进行base64编码时,一切正常,因此我知道此RSA加密有问题。

这是我的iOS通话示例:

OSStatus sanityCheck = SecKeyEncrypt(publicKey,

kSecPaddingPKCS1,

(const uint8_t *) [incomingData bytes],

keyBufferSize,

cipherBuffer,

&cipherBufferSize

);

这是我的Java调用示例:

public static byte[] decryptMessage (byte[] message, PrivateKey privateKey, String algorithm) {

if (message == null || privateKey == null) {

return null;

}

Cipher cipher = createCipher(Cipher.DECRYPT_MODE, privateKey, algorithm, false);

if (cipher == null) {

return null;

}

try {

return cipher.doFinal(message);

}

catch (IllegalBlockSizeException e) {

e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

return null;

}

catch (BadPaddingException e) {

e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

return null;

}

}

private static Cipher createCipher (int mode, Key encryptionKey, String algorithm, boolean useBouncyCastle) {

Cipher cipher;

try {

if (useBouncyCastle) {

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

cipher = Cipher.getInstance(algorithm, "BC");

}

else {

cipher = Cipher.getInstance(algorithm);

}

}

catch (NoSuchAlgorithmException e) {

e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

return null;

}

catch (NoSuchPaddingException e) {

e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

return null;

}

catch (NoSuchProviderException e) {

e.printStackTrace();

return null;

}

try {

cipher.init(mode, encryptionKey);

}

catch (InvalidKeyException e) {

e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

return null;

}

return cipher;

}

我尝试了很多组合,但没有任何效果。

iOS:PKCS1,Java:RSA / ECB / PKCS1Padding

iOS:PKCS1,Java:RSA

iOS:PKCS1,Java:RSA / None / PKCS1Padding(抛出org.bouncycastle.crypto.DataLengthException: input too large for RSA cipher.)

iOS:OAEP,Java:RSA / ECB / OAEPWithSHA-1AndMGF1Padding

iOS:OAEP,Java:RSA / ECB / OAEPWithSHA-256AndMGF1Padding

我还尝试过使用内部Java提供程序以及BouncyCastle提供程序。javax.crypto.BadPaddingException每次都会抛出该get,但是每种组合所传达的信息都是不同的。有的表演Data

must start with zero,有的表演Message is larger than modulus。

在iOS: PKCS1, Java:

RSA不抛出异常,但所得到的解密的byte[]阵列应该是长度16,但它的长度为256,这意味着填充未正确剥离出来。

有人可以帮忙吗?

*编辑 ***

在进行更多测试时,我偶然发现了此页面(http://javadoc.iaik.tugraz.at/iaik_jce/current/iaik/pkcs/pkcs1/RSACipher.html),该页面实际上告诉我RSA

== RSA/None/PKCS1Padding。解密在没有异常的意义上起作用,但是我仍然得到一个解密的密钥,该密钥的byte

[]是长度256而不是长度16。

另一个兴趣点。看来,如果Java服务器具有从iOS设备生成的公钥,并且使用进行Cipher.getInstance("RSA")了加密,则电话能够使用RSA

/ PKCS1正确解码消息。

*编辑2 ***

我看过这些教程,并再次在iOS端浏览了我的代码:

据我所知,我的代码可以正确执行所有操作。一个显着的区别是我保存密钥的方式,因此我尝试用另一种方法保存它:

OSStatus error = noErr;

CFTypeRef persistPeer = NULL;

NSMutableDictionary * keyAttr = [[NSMutableDictionary alloc] init];

keyAttr[(__bridge id) kSecClass] = (__bridge id) kSecClassKey;

keyAttr[(__bridge id) kSecAttrKeyType] = (__bridge id) kSecAttrKeyTypeRSA;

keyAttr[(__bridge id) kSecAttrApplicationTag] = [secKeyWrapper getKeyTag:serverPublicKeyTag];

keyAttr[(__bridge id) kSecValueData] = strippedServerPublicKey;

keyAttr[(__bridge id) kSecReturnPersistentRef] = @YES;

error = SecItemAdd((__bridge CFDictionaryRef) keyAttr, (CFTypeRef *)&persistPeer);

if (persistPeer == nil || ( error != noErr && error != errSecDuplicateItem)) {

NSLog(@"Problem adding public key to keychain");

return;

}

CFRelease(persistPeer);

保存成功,但是最终结果是相同的:解密的AES密钥仍然是256字节长而不是16字节长。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值