iOS - 从指数+模数创建 SecKeyRef

Posted

技术标签:

【中文标题】iOS - 从指数+模数创建 SecKeyRef【英文标题】:iOS - Creating SecKeyRef from exponent+modulus 【发布时间】:2011-08-22 00:17:19 【问题描述】:

我想通过将指数和模数作为私钥来解密 iPhone 上的 RSA 编码 blob。在 Java(使用 javax.crypto)中,这可以通过如下代码轻松实现:

// 1) key
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(myModulus, myPublicExponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
Key pubKey = fact.generatePublic(keySpec);

// 2) cypher
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, keySpec);

// 3) use cypher to decode my block to an output stream

但使用 iPhone 安全 API,我无法创建 SecKeyRef(密钥),只能通过生成一对或导入我没有/不想要的证书。

有没有办法手动创建一个具有模数+指数的键?如果是这样,你能告诉我怎么做吗?

提前致谢

【问题讨论】:

我也有同样的问题。如果你有一些示例代码/链接请帮助我,你能指导我吗? 【参考方案1】:

您的指数和模数是如何编码的?如果它们在 PKCS#12 blob 中,您可以使用 SecPKCS12Import()SecIdentityCopyPrivateKey() 来实现您想要的。

编辑:鉴于您拥有原始密钥,您可能有兴趣查看 Apple 的 -[SecKeyWrapper addPeerPublicKey:keyBits:] 示例 provided。

【讨论】:

谢谢。我的指数和模数没有编码,它们只是存储在内存中的大整数,无论​​是大端还是小端。 谢谢,这个例子看起来不错,但我找不到任何关于导入密钥的预期格式的文档(它只是一组模糊的 592 位);指数是如何编码的,是在模数之后还是之前,等等。有没有相关文档? blog.wingsofhermes.org/?p=42和blog.wingsofhermes.org/?p=75可以互换 @SedateAlien 我还是有点困惑。在我的情况下,它是一个公钥,指数和模数以这种形式出现:<RSAKeyValue><Modulus>yOTe0L1/NCbXDZYdlis82MiTe8VD5WD23S4RDsebJOFzCLbsyb4d+K1M5FB+xPfCkji1zQjPijiToZ7JSj/2ww==</Modulus><Exponent>AWAB</Exponent></RSAKeyValue>我如何从中获取公钥? @pixelfreak..你的问题得到答案了吗?【参考方案2】:

我有一个库,现在可以让您创建二进制数据以导入模数和指数中的 RSA 密钥:

https://github.com/StCredZero/SCZ-BasicEncodingRules-ios

SCZ-BasicEncodingRules-iOS

实施基本编码规则以将 RSA 密钥导入 iOS 使用指数的钥匙串。代码针对带有 ARC 的 iOS 5。

假设您已经有了一个模数和指数 在名为 pubKeyModData 的变量中作为 NSData 的 RSA 公钥和 pubKeyExpData。然后以下代码将创建一个包含该 RSA 的 NSData 公钥,然后您可以将其插入 iOS 或 OS X 钥匙串中。

NSMutableArray *testArray = [[NSMutableArray alloc] init];
[testArray addObject:pubKeyModData];
[testArray addObject:pubKeyExpData];
NSData *testPubKey = [testArray berData];

这将允许您使用 Apple CryptoExercise 示例中 SecKeyWrapper 中的 addPeerPublicKey:keyBits: 方法存储密钥。或者,从底层 API 的角度,可以使用 SecItemAdd()。

NSString * peerName = @"Test Public Key";

NSData * peerTag = 
   [[NSData alloc] 
       initWithBytes:(const void *)[peerName UTF8String] 
       length:[peerName length]];

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

[peerPublicKeyAttr 
   setObject:(__bridge id)kSecClassKey 
   forKey:(__bridge id)kSecClass];
[peerPublicKeyAttr 
   setObject:(__bridge id)kSecAttrKeyTypeRSA 
   forKey:(__bridge id)kSecAttrKeyType];
[peerPublicKeyAttr 
   setObject:peerTag 
   forKey:(__bridge id)kSecAttrApplicationTag];
[peerPublicKeyAttr 
   setObject:testPubKey 
   forKey:(__bridge id)kSecValueData];
[peerPublicKeyAttr 
   setObject:[NSNumber numberWithBool:YES] 
   forKey:(__bridge id)kSecReturnPersistentRef];

sanityCheck = SecItemAdd((__bridge CFDictionaryRef) peerPublicKeyAttr, (CFTypeRef *)&persistPeer);

【讨论】:

我试过berData,得到的公钥与我在.NET 实现中得到的不同。你确定这行得通吗? 我已经使用成功了。你能提供更多的上下文信息吗? 我从一个安卓人那里得到..指数和模数作为字符串,我需要使用:dataUsingEncoding:NSUTF8StringEncoding 来获取 pubKeyModData 和 pubKeyModData?

以上是关于iOS - 从指数+模数创建 SecKeyRef的主要内容,如果未能解决你的问题,请参考以下文章

从模数和指数生成 RSA 公钥

RSA 使用 iOS 和 C# 实现

使用Python从公钥获取RSA指数和模数

RSA:在给定公钥的情况下获取指数和模数

在 Objective-c 中从模数和指数以字节为单位生成 RSA 公钥

从 base64 RSA 公钥生成 SecKeyRef