0

I found something like this question but that didn't work for me

How can I use a PKCS8 RSA DER Private Key in iOS?

Community
  • 1
  • 1

2 Answers2

2

Not easily. Apple would prefer that you use a cert (public key) or identity (.p12 file, public/private key pair), and makes storing raw keys difficult. That especially goes for private keys -- you generally would rather not have unencrypted private keys in your memory space if you can avoid it. On OSX, SecItemImport() works, but not on iOS, though I haven't checked for a couple of OS versions now.

You can force it if you really want, but it needs to be PKCS#1 DER data -- so you have to extract the PKCS#1 key from the PKCS#8 data, which means you have to parse DER by hand.

This is an older example for public key PKCS#8 data:

http://blog.flirble.org/2011/01/05/rsa-public-key-openssl-ios/

Using that code, you can get a SecKeyRef for a public key; private keys are a little different DER structure but similar idea.

The best bet though is to get a .p12 file and use SecPKCS12Import(). That will get you a SecIdentityRef, and from there you can use SecIdentityCopyPrivateKey() to get the private key SecKeyRef.

Carl Lindberg
  • 2,902
  • 18
  • 22
0

Have a look at this GitHub repo. It demonstrates the usage of SecItemImport to load keys for signing and verification.

You should also carefully look at SecExternalFormat enum which has (among others) kSecFormatWrappedPKCS8. This is probably what you're looking for.

Alex Skalozub
  • 2,511
  • 16
  • 15
  • Thanks for answer,any time SecKeyGetBlockSize was raise exception ````bad access````,I couldn't understand reason. – Arthur Sahakyan Feb 15 '16 at 14:58
  • ````NSString* path = [[NSBundle mainBundle] pathForResource:@"private_key" ofType:@"pem"]; NSData *content = [[NSData alloc]initWithContentsOfFile:path]; SecKeyRef privateKey = (__bridge SecKeyRef)(content); if (privateKey){ signedHashBytesSize = SecKeyGetBlockSize(privateKey); }```` – Arthur Sahakyan Feb 15 '16 at 15:31
  • I have found this solution link is below,but ````#include ```` didn't found http://stackoverflow.com/questions/19182158/ios-sign-a-string-with-an-rsa-private-key – Arthur Sahakyan Feb 15 '16 at 15:35
  • You cannot bridge `SecKeyRef` from `NSData`. You need to use `SecItemImport`. – Alex Skalozub Feb 15 '16 at 15:39
  • Have you looked at the repository above? It contains a sample code. – Alex Skalozub Feb 15 '16 at 16:03
  • Unless it has changed recently, I don't think you can use ```SecItemImport``` on iOS for public or private keys. Also, PEM is a different format than DER -- you need to convert to DER first (basically parse the base64 text from the PEM and convert that to data). – Carl Lindberg Feb 15 '16 at 20:48
  • @CarlLindberg I said a bit wrong about `SecItemImport`, sure thing you need to use `SecItemAdd` on iOS instead. But it does allow you to import private and (with little effort) public keys. You just need to specify key attributes correctly. The repo above shows how to do it. But regarding original question, you'll still need to strip PKCS8 encoding (it is likely first 26 bytes of DER) before importing. – Alex Skalozub Feb 15 '16 at 22:23
  • @CarlLindberg just noticed that the repo from my link references the same article you linked in your answer. So we're probably talking about the same approach on importing keys :) – Alex Skalozub Feb 15 '16 at 23:00
  • Yep, that's the same as it has been then. Private keys have a few more bytes you need to strip out -- there is an extra "Version" ASN.1 INTEGER in there before the private key data starts. – Carl Lindberg Feb 15 '16 at 23:02
  • Actually it appears it is *public* key which needs to be stripped. Default OpenSSL DER private key (without PKCS8 encoding) seems to be imported as is. But with PKCS8 in play both need to be stripped. – Alex Skalozub Feb 15 '16 at 23:11
  • Hm, in the ones I dealt with, OpenSSL created PKCS8 private keys too, which needed slightly different stripping. But yes, you need to pull out the raw PKCS1 data which is inside the PKCS8 wrapper in order to get them to work. If you have PKCS1 to begin with, all the better. – Carl Lindberg Feb 15 '16 at 23:17