The first step is to create a self-signed certificate
1. The easiest and fastest way to do this is to open Terminal and use openssl (which comes with Mac OS X) to generate a private key and self-signed x509 certificate.
openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem -days 3650
Just follow the prompts on the command line and type in the contents.
A few notes:
public_key.der is the output self-signed x509 certificate, the one we're going to use.
private_key.pem is the exported private key, which is used for decryption, please keep it safe.
rsa:1024 here 1024 is the key length, 1024 is more secure, if you need more security, you can use 2048, but the cost of encryption and decryption will also increase.
-days: the expiration time of the certificate, be sure to add this parameter, the default expiration time of the certificate is 30 days, generally we do not want the certificate so short on the expiration time, so write a more appropriate number of days, for example, here 3650 (10 years).
In fact, this one line of command contains several steps (I'm looking at the following steps because I already have a private_key.pem private key on hand, and I want to use this directly to generate an x509 certificate, which is what I'm using in 2-3 below)
1) Create the private key
openssl genrsa - out private_key.pem 1024
2)Create a certificate request (follow the prompts for information)
openssl req -new -out cert.csr -key private_key.pem
3)Self-sign the root certificate
openssl x509 -req -in cert.csr -out public_key.der -outform der -signkey private_key.pem -days 3650
2. Verify the certificate. Drag public_key.der to xcode, if there is no problem with the file then you can open it directly in xcode and see various information about the certificate.
Step 2, use public_key.der for encryption.
1. Import Security.framework.
2. Put public_key.der into mainBundle (usually just drag it to Xcode).
3. Read the public key from public_key.der.
4. Encrypt it.
Here's the reference code (it can only be used to encrypt content less than or equal to 116 bytes long, and is suitable for encrypting passwords. ARC is used, but it is still important to note that some resources need to be released using CFRealse)
RSA.h
//
// RSA.h
//
#import Foundation.h>
@interface RSA : NSObject {
SecKeyRef publicKey;
SecCertificateRef certificate;
SecPolicyRef policy;
SecTrustRef trust;
size_t maxPlainLen;
}
- (NSData *) encryptWithData:(NSData *)content;
- (NSData *) encryptWithString:(NSString *)content;
@end
RSA.m
//
// RSA.m
//
#import "RSA.h"
@implementation RSA
- (id)init {
self = [super init];
NSString *publicKeyPath = [[NSBundle mainBundle] pathForResource:@"public_key"
ofType:@"der"];
if ( publicKeyPath == nil) {
NSLog(@"Can not find pub.der");
return nil;
}
NSDate *publicKeyFileContent = [NSData dataWithContentsOfFile:publicKeyPath];
if (publicKeyFileContent == nil) {
NSLog(@"Can not read from pub.der");
return nil )
}
certificate = SecCertificateCreateWithData(kCFAllocatorDefault, ( __bridge CFDataRef)publicKeyFileContent);
if ( certificate == nil) {
NSLog(@"Can not read certificate from pub.der");
return nil;
}
policy = SecPolicyCreateBasicX509();
OSStatus returnCode = SecTrustCreateWithCertificates(certificate, policy, &trust);
if ( returnCode ! = 0) {
NSLog(@"SecTrustCreateWithCertificates fail. Error Code: %ld", returnCode);
return nil;
}
SecTrustResultType trustResultType;
returnCode = SecTrustEvaluate(trust, &trustResultType);
if (returnCode ! = 0) {
NSLog(@"SecTrustEvaluate fail. Error Code: %ld", returnCode);
return nil;
}
publicKey = SecTrustCopyPublicKey (trust);
if (publicKey == nil) {
NSLog(@"SecTrustCopyPublicKey fail");
return nil;
}
maxPlainLen = SecKeyGetBlockSize(publicKey) - 12;
return self;
}
- (NSData *) encryptWithData:(NSData *)content {
size_t plainLen = [content length];
if (plainLen > maxPlainLen) {
NSLog(@"content(%ld) is too long, must < %ld", plainLen, maxPlainLen);
return nil;
}
void *plain = malloc(plainLen);
[content getBytes:plain
length:plainLen];
size_t cipherLen = 128; // The current RSA key length is 128 bytes
void *cipher = malloc(cipherLen);
OSStatus returnCode = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, plain,
plainLen, cipher, &cipherLen);
NSData *result = nil;
if (returnCode ! = 0) {
NSLog(@"SecKeyEncrypt failed. Error Code: %ld", returnCode);
}
else {
result = [NSData dataWithBytes:cipher
length:cipherLen
NSData *result = nil;
If (returnCode ! p>length:cipherLen];
}
free(plain);
free(cipher);
return result;
}
- (NSData *) encryptWithString. (NSString *)content {
return [self encryptWithData:[content dataUsingEncoding:NSUTF8StringEncoding]];
}
- (void) dealloc{
CFRelease(certificate);
CFRelease(trust);
CFRelease(policy);
CFRelease(publicKey);
}
@end
Usage:
RSA *rsa = [[RSA alloc] init];
if (rsa ! = nil) {
NSLog(@"%@",[rsa encryptWithString:@"test"]);
}
else {
NSLog(@"init rsa error");
}