12

I would like to decrypt a RSA-encoded blob on iPhone, by having an exponent and modulus as private key. In Java (with javax.crypto), this could be easily achieved by code like this:

// 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

But with the iPhone security API I can't create a SecKeyRef (key) other than by generating a pair or importing a certificate, which I don't have/want.

Is there a way to create a key manually having a modulus + exponent? If so, can you give me a clue on how?

Thanks in advance

Hashi
  • 175
  • 1
  • 6

2 Answers2

1

I have a library that lets you create the binary data to import RSA keys in modulus and exponent now:

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

SCZ-BasicEncodingRules-iOS

Implementation of Basic Encoding Rules to enable import of RSA keys to iOS KeyChain using exponent. Code targets iOS 5 with ARC.

Let's say you already have a modulus and exponent from an RSA public key as an NSData in variables named pubKeyModData and pubKeyExpData. Then the following code will create an NSData containing that RSA public key, which you can then insert into the iOS or OS X Keychain.

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

This would allow you to store the key using the addPeerPublicKey:keyBits: method from SecKeyWrapper in the Apple CryptoExercise example. Or, from the perspective of the low-level API, you can use 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);
pixelfreak
  • 17,714
  • 12
  • 90
  • 109
StCredZero
  • 464
  • 3
  • 13
  • I tried `berData`, the resulting public key is different from what I got with .NET implementation. Are you sure this works? – pixelfreak Oct 20 '13 at 05:19
  • I have used it successfully. Could you give more contextual information? – StCredZero Nov 07 '13 at 20:38
  • I have got.. exponent and modulus as string from an android guy, do I need to use: dataUsingEncoding:NSUTF8StringEncoding to obtain pubKeyModData and pubKeyModData? – Devarshi May 14 '14 at 09:51
1

How are your exponent and modulus encoded? If they're in a PKCS#12 blob, you can use SecPKCS12Import() and SecIdentityCopyPrivateKey() to achieve what you want.

EDIT: Given that you have the raw keys, you might be interested in looking at the -[SecKeyWrapper addPeerPublicKey:keyBits:] example provided by Apple.

Aidan Steele
  • 10,999
  • 6
  • 38
  • 59
  • Thanks. My exponent and modulus are not encoded, they are just big integers stored in memory either as big or little endian. – Hashi May 10 '11 at 22:41
  • Thanks, this example seems nice but I can't find any documentation on the expected format for importing the key (it's just an obscure set of 592 bits); how is the exponent encoded, is it after or before the modulus, etc. Is there any documentation on that? – Hashi May 17 '11 at 09:39
  • http://blog.wingsofhermes.org/?p=42 and http://blog.wingsofhermes.org/?p=75 Can be used for interchange – Hashi May 17 '11 at 16:04
  • 2
    @SedateAlien I am still a bit confused. In my case it's a public key and the exponent and modulus comes in this form: `yOTe0L1/NCbXDZYdlis82MiTe8VD5WD23S4RDsebJOFzCLbsyb4d+K1M5FB+xPfCkji1zQjPijiToZ7JSj/2ww==AWAB` How do I get a public key out of that? – pixelfreak Oct 18 '13 at 21:17
  • 1
    @pixelfreak..did you get answer for your query? – Devarshi May 12 '14 at 10:01
  • I don't see how this answer demonstrates or explains how to create a `SecKeyRef` object from an exponent + modulus. – Adil Hussain Jun 08 '17 at 10:55