title: X.509 RSA Encryption/Decryption iOS
body: <p>I need to implement encryption / decryption using a X.509 RSA public/private key pair.</p>
  
  <p>So far, I have something which I think will work for encryption, but I have no way of decrypting to check. Everything I try has issues reading the private key. </p>
  
  <h2>Generating the key pairs (returns a <code>.der</code> and a <code>.pem</code>)</h2>
  
  <pre><code>openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem -days 3650
  </code></pre>
  
  <h2>Encryption (Not sure if this works, but looks like it does)</h2>
  
  <pre><code>+ (NSData *) RSAEncryptData:(NSData *)content {
      SecKeyRef publicKey;
      SecCertificateRef certificate;
      SecPolicyRef policy;
      SecTrustRef trust;
      size_t maxPlainLen;
  
      NSString *publicKeyPath = [[NSBundle mainBundle] pathForResource:@"public_key" ofType:@"der"];
      NSData *base64KeyData = [NSData dataWithContentsOfFile:publicKeyPath];
  
      certificate = SecCertificateCreateWithData(kCFAllocatorDefault, ( __bridge CFDataRef) base64KeyData);
      if (certificate == nil) {
          NSLog(@"Can not read certificate from data");
          return nil;
      }
  
      policy = SecPolicyCreateBasicX509();
      OSStatus returnCode = SecTrustCreateWithCertificates(certificate, policy, &amp;trust);
      if (returnCode != 0) {
          NSLog(@"SecTrustCreateWithCertificates fail. Error Code: %d", (int)returnCode);
          return nil;
      }
  
      SecTrustResultType trustResultType;
      returnCode = SecTrustEvaluate(trust, &amp;trustResultType);
      if (returnCode != 0) {
          return nil;
      }
  
      publicKey = SecTrustCopyPublicKey(trust);
      if (publicKey == nil) {
          NSLog(@"SecTrustCopyPublicKey fail");
          return nil;
      }
  
      maxPlainLen = SecKeyGetBlockSize(publicKey) - 12;
  
  
      size_t plainLen = [content length];
      if (plainLen &gt; maxPlainLen) {
          NSLog(@"content(%ld) is too long, must &lt; %ld", plainLen, maxPlainLen);
          return nil;
      }
  
      void *plain = malloc(plainLen);
      [content getBytes:plain
                 length:plainLen];
  
      size_t cipherLen = 128; // currently RSA key length is set to 128 bytes
      void *cipher = malloc(cipherLen);
  
      OSStatus encryptReturnCode = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, plain,
                                          plainLen, cipher, &amp;cipherLen);
  
      NSData *result = nil;
      if (encryptReturnCode != 0) {
          NSLog(@"SecKeyEncrypt fail. Error Code: %d", (int)returnCode);
      }
      else {
          result = [NSData dataWithBytes:cipher
                                  length:cipherLen];
      }
  
      free(plain);
      free(cipher);
  
      return result;
  }
  </code></pre>
  
  <h2>Decryption</h2>
  
  <p>I have tried using OpenSSL's <code>PEM_read_X509</code> also <code>PEM_read_RSAPrivateKey</code>, but both fail to read the cert. I have not even gotten past that. If I could do this without having a dependency on the OpenSSL library, that would be even better.</p>
  
  <pre><code>+(void)readTest{
      FILE *fp;
      X509 *x;
      NSString *path =[[NSBundle mainBundle] pathForResource:@"private_key" ofType:@"pem"];
      fp=fopen([path UTF8String],"r");
  
      x=NULL;
      PEM_read_X509(fp,&amp;x,NULL,NULL); // I have also tried PEM_read_RSAPrivateKey
  
      if (x == NULL) {
          NSLog(@"Cant Read File"); // This ALWAYS fires
      }
  
      fclose(fp);
      X509_free(x);
  }
  </code></pre>
  
  <p>If someone could help me out with encryption/decryption using X.509 RSA pairs, I'd appreciate it. Thanks.</p>