SecKeyRef always nil in Xcode 7 Beta 5

Hi Guys,


Recenlty I have been testing my code in iOS 9 with Xcode 7 Beta 5. In my app, I am using + (SecKeyRef) addPeerPublicKey:(NSString *) peerName withPublicKey:(NSData *) publicKey method to generate public key from exponent and modulus. It turns out that SecKeyRef generate is always nil in iOS 9 but works well in iOS 8. Is it bug for the Xcode 7 Beta 5 or There are several changing that i need to do in order to make it works in iOS 9?


Please help.


Thanks.


Best Regards,


Chris

Accepted Reply

Your public key is malformed. Consider this:

$ # I just put the hex dump into a file called "tmp.asn1".
$
$ hexdump -Cv tmp.asn1
00000000  30 81 88 02 81 80 d4 e7  f6 50 36 5c 80 bd 72 01  |0........P6\..r.|
00000010  42 96 84 10 74 c4 97 67  ab 23 53 9f c5 b4 a3 a2  |B...t..g.#S.....|
00000020  e1 42 99 fe 48 42 72 92  24 75 2a 76 a5 a7 3a 62  |.B..HBr.$u*v..:b|
00000030  65 f5 5d 81 80 66 48 9a  e1 83 43 5a ed c4 0e ba  |e.]..fH...CZ....|
00000040  48 e5 3b 1a 84 d8 48 9b  17 e1 fa 11 6a c5 c4 0e  |H.;...H.....j...|
00000050  cb f0 fa 4f c7 3c cf 4c  ea 79 86 7b 82 59 bc a6  |...O.<.L.y.{.Y..|
00000060  00 f7 80 5c 8f a8 02 8e  63 52 35 4c cd 4f 18 62  |...\....cR5L.O.b|
00000070  68 a8 f0 ae e6 92 bb 27  47 48 dc 35 00 ea c8 6f  |h......'GH.5...o|
00000080  16 19 39 b2 c9 0f 02 03  01 00 01                 |..9........|
0000008b
$
$ # Now let's dump that file.
$
$ dumpasn1 tmp.asn1
   0  136: SEQUENCE {
   3  128:   INTEGER
         :     D4 E7 F6 50 36 5C 80 BD 72 01 42 96 84 10 74 C4
         :     97 67 AB 23 53 9F C5 B4 A3 A2 E1 42 99 FE 48 42
         :     72 92 24 75 2A 76 A5 A7 3A 62 65 F5 5D 81 80 66
         :     48 9A E1 83 43 5A ED C4 0E BA 48 E5 3B 1A 84 D8
         :     48 9B 17 E1 FA 11 6A C5 C4 0E CB F0 FA 4F C7 3C
         :     CF 4C EA 79 86 7B 82 59 BC A6 00 F7 80 5C 8F A8
         :     02 8E 63 52 35 4C CD 4F 18 62 68 A8 F0 AE E6 92
         :     BB 27 47 48 DC 35 00 EA C8 6F 16 19 39 B2 C9 0F
         :     Error: Integer has a negative value.
134    3:   INTEGER 65537
         :   }

0 warnings, 1 error.

Note If you’re monkeying with crypto stuff, I strongly recommend that you get to know the

dumpasn1
tool.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

Lots of folks use this technique so I’d be surprised if it was broken in general. Please post a specific example of what’s failing, that is, both the code and a hex dump of an example key.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for the reply. Here is my code about the these for PeerPublicKey when generating peerKeyRef from SecItemCopyMatching becomes nil:


+ (SecKeyRef) addPeerPublicKey:(NSString *) peerName withPublicKey:(NSData *) publicKey {

OSStatus sanityCheck = noErr;

SecKeyRef peerKeyRef = NULL;

CFTypeRef persistPeer = NULL;


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:publicKey forKey:(__bridge id)kSecValueData];

[peerPublicKeyAttr setObject:[NSNumber numberWithUnsignedInteger:2048] forKey:(__bridge id)kSecAttrKeySizeInBits];


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


if (persistPeer) {

peerKeyRef = (SecKeyRef)[self getPersistentKeyRefWithKeyRef:persistPeer];

} else {

[peerPublicKeyAttr removeObjectForKey:(__bridge id)kSecValueData];

[peerPublicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];

sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef) peerPublicKeyAttr, (CFTypeRef *)&peerKeyRef);

}


if (persistPeer) CFRelease(persistPeer);


return peerKeyRef;

}


Here is my code for generating public key from modulus and exponent:


func encryption(password: String) -> String

{

let pubKeyModData = Base64.decode(modulusPublickKey)

let pubKeyExpData = Base64.decode(exponentPublicKey)

let testArray = NSMutableArray()

testArray.addObject(pubKeyModData)

testArray.addObject(pubKeyExpData)


let testPubKey = testArray.berData()


var publicKey: SecKeyRef


let dataToCipher = password.dataUsingEncoding(NSUTF8StringEncoding)

publicKey = SecKeyEncryption.addPeerPublicKey("***.publickey", withPublicKey: testPubKey).takeRetainedValue()


let cipherData = SecKeyEncryption.wrapSymmetricKey(dataToCipher, keyRef: publicKey)

let newStr = cipherData.base64EncodedString()


return newStr

}


And I used BasicEncodingRules for creating testPubKey:


- (NSData*)berData

{

NSMutableData *berData = [[NSMutableData alloc] init];

[berData appendData:[self berHeader]];

[berData appendData:[self berContents]];

return berData;

}


- (NSData*)berHeader

{

NSMutableData *berHeader = [[NSMutableData alloc] init];

[berHeader appendBytes:[self berTag] length:1];

[berHeader appendData:[self lengthStorageData]];

return berHeader;

}

- (NSData*)berContents {

[self raiseUnimplemented];

return nil;

}


- (void)raiseUnimplemented {

[NSException

raise:@"Invalid BER translation"

format:@"unimplemented for this type"];

}


Please help what's wrong in my code.

Here is my code about the these for PeerPublicKey…

OK. But I also asked for a dump of an example key. You can generate such a dump by simply adding this line to the start of

+addPeerPublicKey:withPublicKey:
.
NSLog(@"publicKey = %@", publicKey);

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi Mr. Eskimo,


Thanks for your reply and sorry I forgot to give you a dump of example key. Here is my example key:


publicKey = <30818802 8180d4e7 f650365c 80bd7201 42968410 74c49767 ab23539f c5b4a3a2 e14299fe 48427292 24752a76 a5a73a62 65f55d81 8066489a e183435a edc40eba 48e53b1a 84d8489b 17e1fa11 6ac5c40e cbf0fa4f c73ccf4c ea79867b 8259bca6 00f7805c 8fa8028e 6352354c cd4f1862 68a8f0ae e692bb27 4748dc35 00eac86f 161939b2 c90f0203 010001>

Hope you can help me.. 🙂

Thanks.

Your public key is malformed. Consider this:

$ # I just put the hex dump into a file called "tmp.asn1".
$
$ hexdump -Cv tmp.asn1
00000000  30 81 88 02 81 80 d4 e7  f6 50 36 5c 80 bd 72 01  |0........P6\..r.|
00000010  42 96 84 10 74 c4 97 67  ab 23 53 9f c5 b4 a3 a2  |B...t..g.#S.....|
00000020  e1 42 99 fe 48 42 72 92  24 75 2a 76 a5 a7 3a 62  |.B..HBr.$u*v..:b|
00000030  65 f5 5d 81 80 66 48 9a  e1 83 43 5a ed c4 0e ba  |e.]..fH...CZ....|
00000040  48 e5 3b 1a 84 d8 48 9b  17 e1 fa 11 6a c5 c4 0e  |H.;...H.....j...|
00000050  cb f0 fa 4f c7 3c cf 4c  ea 79 86 7b 82 59 bc a6  |...O.<.L.y.{.Y..|
00000060  00 f7 80 5c 8f a8 02 8e  63 52 35 4c cd 4f 18 62  |...\....cR5L.O.b|
00000070  68 a8 f0 ae e6 92 bb 27  47 48 dc 35 00 ea c8 6f  |h......'GH.5...o|
00000080  16 19 39 b2 c9 0f 02 03  01 00 01                 |..9........|
0000008b
$
$ # Now let's dump that file.
$
$ dumpasn1 tmp.asn1
   0  136: SEQUENCE {
   3  128:   INTEGER
         :     D4 E7 F6 50 36 5C 80 BD 72 01 42 96 84 10 74 C4
         :     97 67 AB 23 53 9F C5 B4 A3 A2 E1 42 99 FE 48 42
         :     72 92 24 75 2A 76 A5 A7 3A 62 65 F5 5D 81 80 66
         :     48 9A E1 83 43 5A ED C4 0E BA 48 E5 3B 1A 84 D8
         :     48 9B 17 E1 FA 11 6A C5 C4 0E CB F0 FA 4F C7 3C
         :     CF 4C EA 79 86 7B 82 59 BC A6 00 F7 80 5C 8F A8
         :     02 8E 63 52 35 4C CD 4F 18 62 68 A8 F0 AE E6 92
         :     BB 27 47 48 DC 35 00 EA C8 6F 16 19 39 B2 C9 0F
         :     Error: Integer has a negative value.
134    3:   INTEGER 65537
         :   }

0 warnings, 1 error.

Note If you’re monkeying with crypto stuff, I strongly recommend that you get to know the

dumpasn1
tool.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi Eskimo, could you take a look at this?

https://forums.developer.apple.com/message/38361#38361

Hi Eskimo,


Why the public key can generate in iOS 8 SDK? I used Base64 encode decode for exponent & modulus.


Please enlight me.


Best Regards,


Chris

Why the public key can generate in iOS 8 SDK?

It’s not uncommon for different releases of the OS to have varying behaviour when it comes to parsing malformed data.

Given that iOS does not have an API for converting an exponent and modulus into a key, you have three choices here:

  • Continue using your own code for this, fixing it to generate the ASN.1 data structure correctly (A).

  • Adopt some third-party ASN.1 library (B).

  • Change the code that sent you the exponent and modulus to instead send you a certificate (iOS has nice APIs for dealing with certificates) (C).

In general I recommend C. Given that the server is likely to have a full-feature security toolbox, it should be easy to do this on the server side.

If you stick with approach A and get completely stuck, please open a DTS tech support incident and we can take a look at your code in more detail.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I found a solution, in the hope that useful to you。http://blog.csdn.net/ylgwhyh/article/details/49756209

I have th same issue with following public key:

  0 290: SEQUENCE {
  4  13:   SEQUENCE {
  6   9:     OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
17   0:     NULL
       :     }
19 271:   BIT STRING, encapsulates {
24 266:     SEQUENCE {
28 257:       INTEGER
       :         00 BC 90 A3 F1 69 16 68 73 2A BE CE AF 2D 2C 08
       :         8C C9 2A 45 B2 67 2A 12 88 82 82 DF C1 2C B2 2A
       :         B9 55 1D F6 B5 59 19 4D 99 8F F3 4A 51 3A EF AC
       :         19 A8 AE 8C 6C 21 12 53 54 A1 EB E9 DD E0 A7 07
       :         81 63 63 02 18 CF 64 47 A5 46 DB DF 6A 5C 12 C1
       :         3C 20 24 F8 C9 15 40 03 4E 7E BD 90 85 4E 82 E1
       :         3C AE BE 7F 95 C5 D1 59 DA 96 83 EB BA 57 59 56
       :         C1 95 0C 4B B1 EB AF 58 59 40 12 52 C9 89 65 7E
       :         20 96 92 CF BE 66 ED 52 64 8B 34 D6 35 28 1E E8
       :         A1 3F 26 34 D4 80 6F AF B5 77 0B C3 E9 FA 47 69
       :         B0 10 78 0D 3F 7E C3 59 96 87 54 1C 10 E0 6D 2D
       :         B2 EB 06 D9 C1 76 11 1B D4 96 16 3B 00 08 8E AB
       :         50 51 4B 1D 5D 04 AC 18 48 7A BE CD 97 DA 82 AE
       :         09 7A B6 9A B4 FB CD 93 4E CF 0F 10 1E 58 81 BC
       :         02 E2 2C 3F 7D 46 60 54 A2 6C AE F8 D6 25 E9 ED
       :         07 69 78 51 F0 17 EE BC 8D DB 22 ED 77 86 B9 F2
       :         83
289   3:       INTEGER 65537
       :       }
       :     }
       :   }


Is it malformed?

hexdump of publicKey file

00000000  30 82 01 22 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |0.."0...*.H.....|
00000010  01 05 00 03 82 01 0f 00  30 82 01 0a 02 82 01 01  |........0.......|
00000020  00 bc 90 a3 f1 69 16 68  73 2a be ce af 2d 2c 08  |.....i.hs*...-,.|
00000030  8c c9 2a 45 b2 67 2a 12  88 82 82 df c1 2c b2 2a  |..*E.g*......,.*|
00000040  b9 55 1d f6 b5 59 19 4d  99 8f f3 4a 51 3a ef ac  |.U...Y.M...JQ:..|
00000050  19 a8 ae 8c 6c 21 12 53  54 a1 eb e9 dd e0 a7 07  |....l!.ST.......|
00000060  81 63 63 02 18 cf 64 47  a5 46 db df 6a 5c 12 c1  |.cc...dG.F..j\..|
00000070  3c 20 24 f8 c9 15 40 03  4e 7e bd 90 85 4e 82 e1  |< $...@.N~...N..|
00000080  3c ae be 7f 95 c5 d1 59  da 96 83 eb ba 57 59 56  |<......Y.....WYV|
00000090  c1 95 0c 4b b1 eb af 58  59 40 12 52 c9 89 65 7e  |...K...XY@.R..e~|
000000a0  20 96 92 cf be 66 ed 52  64 8b 34 d6 35 28 1e e8  | ....f.Rd.4.5(..|
000000b0  a1 3f 26 34 d4 80 6f af  b5 77 0b c3 e9 fa 47 69  |.?&4..o..w....Gi|
000000c0  b0 10 78 0d 3f 7e c3 59  96 87 54 1c 10 e0 6d 2d  |..x.?~.Y..T...m-|
000000d0  b2 eb 06 d9 c1 76 11 1b  d4 96 16 3b 00 08 8e ab  |.....v.....;....|
000000e0  50 51 4b 1d 5d 04 ac 18  48 7a be cd 97 da 82 ae  |PQK.]...Hz......|
000000f0  09 7a b6 9a b4 fb cd 93  4e cf 0f 10 1e 58 81 bc  |.z......N....X..|
00000100  02 e2 2c 3f 7d 46 60 54  a2 6c ae f8 d6 25 e9 ed  |..,?}F`T.l...%..|
00000110  07 69 78 51 f0 17 ee bc  8d db 22 ed 77 86 b9 f2  |.ixQ......".w...|
00000120  83 02 03 01 00 01                                 |......|
00000126

Your key is wrapped in an ASN.1

SubjectPublicKeyInfo
structure. The iOS RSA import and export APIs expect a ‘*****’
RSAPublicKey
structure. For testing purposes you can get the latter from the former by chopping the first 24 bytes off the data (in your
dumpasn1
output, note that this is the offset on line 7). In product it would behove you to generate the key without that wrapper.

ps iOS 10 added much nicely APIs for importing and exporting keys, namely,

SecKeyCreateWithData
and
SecKeyCopyExternalRepresentation
.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

WWDC runs Mon, 5 Jun through to Fri, 9 Jun. During that time all of DTS will be at the conference, helping folks out face-to-face. http://developer.apple.com/wwdc/