How to sign a string under iOS using encrypted key?
Question: I have keys created in Java. The private key is PKCS#8 encrypted, in PEM
string.

Here is an example of using the private key with M2Crypto in Python:

    
    
    from M2Crypto import EVP, BIO
    privpem = "-----BEGIN ENCRYPTED PRIVATE KEY-----\nMIICoTAbBgoqhkiG9w0BDAEDMA0ECFavEvdkv3fEAgEUBIICgAWvHvH6OktLiaaqo9v+X6XEuY3M\nZr465VmZWzP9nsbTqwSKQQjseiD/rWAxK7RS+V+hit5ZxlNRAUbkg0kwl8SRNX3v6q8noJtcB0OY\ndBEuNJDmWHMHh8qcnfRYc9WXPPmWdjQM2AkfZNfNOxHVlOMhancScy6P4h3Flri9VyUE8w2/zZqK\nBAd2w39V7gprCQXnnNenNuvr4p8MjsdBm8jh00o2HJzN0I6u+9s7M3qLXxwxNepptgU6Qt6eKHi6\njpsV/musVaohLhFMFAzQ87FeGvz/W8dyS9BtAKMRSuDu/QdWIJMRNKkPT0Tt1243V3tzXVXLjz0u\nm/FX6kfxL8r+eGtTr6NKTG75TJfooQzN/v08OEbmvYD/mfptmZ7uKezOGxDmgynn1Au7T/OxKFhx\nWZHpb9OFPIU0uiriUeyY9sbDVJ054zQ/Zd5+iaIjX5RsLoB4J+pfr4HuiVIZVj+Ss2rnPsOY3SjM\ntbHIFp/fLr/HODcDA5eYADRGpBIL9//Ejgzd7OqpU0mdajzZHcMTjeXfWB0cc769bFyHb3Ju1zNO\ng4gNN1H1kOMAXMF7p6r25f6v1BRS6bQyyiFz7Hs7h7JBylbBAgQJgZvv9Ea3XTMy+DIPMdepqu9M\nXazmmYJCtdLAfLBybWsfSBU5K6Pm6+Bwt6mPsuvYQBrP3h84BDRlbkntxUgaWmTB4dkmzhMS3gsY\nWmHGb1N+rn7xLoA70a3U/dUlI7lPkWBx9Sz7n8JlH3cM6jJUmUbmbAgHiyQkZ2mf6qo9qlnhOLvl\nFiG6AY+wpu4mzM6a4BiGMNG9D5rnNyD16K+p41LsliI/M5C36PKeMQbwjJKjmlmWDX0=\n-----END ENCRYPTED PRIVATE KEY-----\n"
    
    msg = "This is a message."
    privkeybio = BIO.MemoryBuffer(privpem)
    privkey = EVP.load_key_bio(privkeybio) #pw: 123456
    privkey.sign_init()
    privkey.sign_update(msg)
    print privkey.sign_final().encode('base64')
    

And here is example of how I can use the PEM (with header and footer stripped
off) in Java:

    
    
    String msg = "This is a message.";
    String privpem = "MIICoTAbBgoqhkiG9w0BDAEDMA0ECFavEvdkv3fEAgEUBIICgAWvHvH6OktLiaaqo9v+X6XEuY3M\nZr465VmZWzP9nsbTqwSKQQjseiD/rWAxK7RS+V+hit5ZxlNRAUbkg0kwl8SRNX3v6q8noJtcB0OY\ndBEuNJDmWHMHh8qcnfRYc9WXPPmWdjQM2AkfZNfNOxHVlOMhancScy6P4h3Flri9VyUE8w2/zZqK\nBAd2w39V7gprCQXnnNenNuvr4p8MjsdBm8jh00o2HJzN0I6u+9s7M3qLXxwxNepptgU6Qt6eKHi6\njpsV/musVaohLhFMFAzQ87FeGvz/W8dyS9BtAKMRSuDu/QdWIJMRNKkPT0Tt1243V3tzXVXLjz0u\nm/FX6kfxL8r+eGtTr6NKTG75TJfooQzN/v08OEbmvYD/mfptmZ7uKezOGxDmgynn1Au7T/OxKFhx\nWZHpb9OFPIU0uiriUeyY9sbDVJ054zQ/Zd5+iaIjX5RsLoB4J+pfr4HuiVIZVj+Ss2rnPsOY3SjM\ntbHIFp/fLr/HODcDA5eYADRGpBIL9//Ejgzd7OqpU0mdajzZHcMTjeXfWB0cc769bFyHb3Ju1zNO\ng4gNN1H1kOMAXMF7p6r25f6v1BRS6bQyyiFz7Hs7h7JBylbBAgQJgZvv9Ea3XTMy+DIPMdepqu9M\nXazmmYJCtdLAfLBybWsfSBU5K6Pm6+Bwt6mPsuvYQBrP3h84BDRlbkntxUgaWmTB4dkmzhMS3gsY\nWmHGb1N+rn7xLoA70a3U/dUlI7lPkWBx9Sz7n8JlH3cM6jJUmUbmbAgHiyQkZ2mf6qo9qlnhOLvl\nFiG6AY+wpu4mzM6a4BiGMNG9D5rnNyD16K+p41LsliI/M5C36PKeMQbwjJKjmlmWDX0=";
    byte [] privkeybytes = Base64.decode(privpem);
    
    EncryptedPrivateKeyInfo encprivki = new EncryptedPrivateKeyInfo(privkeybytes);
    
    Cipher cipher = Cipher.getInstance(encprivki.getAlgName());
    PBEKeySpec pbeKeySpec = new PBEKeySpec("123456".toCharArray());
    SecretKeyFactory secFac = SecretKeyFactory.getInstance(encprivki.getAlgName());
    Key pbeKey = secFac.generateSecret(pbeKeySpec);
    AlgorithmParameters algParams = encprivki.getAlgParameters();
    cipher.init(Cipher.DECRYPT_MODE, pbeKey, algParams);
    KeySpec pkcs8KeySpec = encprivki.getKeySpec(cipher);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PrivateKey pk = kf.generatePrivate(pkcs8KeySpec);
    
    Signature sig = Signature.getInstance("SHA1withRSA");
    sig.initSign(pk);
    sig.update(msg.getBytes("UTF8"));
    byte[] signatureBytes = sig.sign();
    String b = Base64.encodeBytes(signatureBytes, Base64.DO_BREAK_LINES);
    System.out.println(b); // Display the string.
    

How would this be done in iOS? I have looked at the CryptoExercise, in
particular the SecKeyWrapper, but there is lots going on there, and it's
beyond me.

I am not personally going to be doing the iOS development, but I need some
code to give to the developer to at least show more or less how to do it. The
developer is more a UI type and not familiar with crypto. (Neither am I but
that is a different story...)

And while we're at it, how to verify a signature against a string public key
PEM? I won't put the Java and Python examples here as they are pretty straight
forward.


Answer: I had the same problem last week. The CommonCrypt library on iOS is very nice
for symmetric key encryption, but it's just too much hassle dealing with the
keyring to do simple public key things. After spending about half an hour
poking at it I just included OpenSSL. [OpenSSL-
Xcode](https://github.com/sjlombardo/openssl-xcode) made this trivial to set
up - just drop the project and the OpenSSL tarball in, set your target to link
with libssl, and you're good to go.

The OpenSSL code looks nearly the same as the M2Crypto one.

