Mac下生成RSA密钥
MAC OS自带了OpenSSL,直接在命令行里使用OPENSSL就可以。
打开命令行工具,然后输入 openssl打开openssl,接着只要三句命令就可以搞定。
第一句命令生成1024位私钥;
OpenSSL> genrsa -out rsa_private_key.pem 1024
第二句命令把RSA私钥转换成PKCS8格式,密码为空就行;
pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM –nocrypt
第三句命令生成公钥。
rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
iOS上并没有直接的RSA加密API。但是iOS提供了x509的API,而x509是支持RSA加密的。因此,我们可以通过制作自签名的x509证书(由于对安全性要求不高,我们并不需要使用CA认证的证书),再调用x509的相关API来进行加密。
1)创建证书请求(按照提示输入信息)
2)自签署根证书
2.验证证书。把public_key.der拖到xcode中,如果文件没有问题的话,那么就可以直接在xcode中打开,看到证书的各种信息。
也可以一行搞定!
最简单快捷的方法,打开Terminal,使用openssl(Mac OS X自带)生成私钥和自签名的x509证书。
按照命令行的提示输入内容就行了。
几个说明:
public_key.der是输出的自签名的x509证书,即我们要用的。
private_key.pem是输出的私钥,用来解密的,请妥善保管。
rsa:1024这里的1024是密钥长度,1024是比较安全的,如果需要更安全的话,可以用2048,但是加解密代价也会增加。
-days:证书过期时间,一定要加上这个参数,默认的证书过期时间是30天,一般我们不希望证书这么短就过期,所以写上比较合适的天数,例如这里的3650(10年)。
第二步,使用public_key.der来进行加密。
1.导入Security.framework。
2.把public_key.der放到mainBundle中(一般直接拖到Xcode就行啦)。
3.从public_key.der读取公钥。
4.加密。
下面是参考代码(只能用于加密长度小于等于116字节的内容,适合于对密码进行加密。使用了ARC,不过还是要注意部分资源需要使用CFRealse来释放)
+ (SecKeyRef) getPublicKey{ // 从公钥证书文件中获取到公钥的SecKeyRef指针 /* Open and parse the cert*/ NSString *path = [[NSBundle mainBundle] pathForResource:@"public_key" ofType:@"der"]; NSData*certData =[NSData dataWithContentsOfFile:path]; SecCertificateRef cert =SecCertificateCreateWithData(kCFAllocatorDefault,(CFDataRef)certData); SecPolicyRef policy =SecPolicyCreateBasicX509(); SecTrustRef trust; OSStatus status =SecTrustCreateWithCertificates(cert, policy,&trust); /* You can ignore the SecTrustResultType, but you have to run SecTrustEvaluate * before you can get the public key */ SecTrustResultType trustResult; if(status == noErr) { status =SecTrustEvaluate(trust,&trustResult); } /* Now grab the public key from the cert */ SecKeyRef publicKey =SecTrustCopyPublicKey(trust); /* Free the Security Framework! */ CFRelease(cert); CFRelease(policy); CFRelease(trust); return publicKey; } + (NSMutableData*) rsaEncryptString:(NSString*) string{ SecKeyRef key = [self getPublicKey]; size_t cipherBufferSize = SecKeyGetBlockSize(key); uint8_t *cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t)); NSData *stringBytes = [string dataUsingEncoding:NSUTF8StringEncoding]; size_t blockSize = cipherBufferSize - 11; size_t blockCount = (size_t)ceil([stringBytes length] / (double)blockSize); NSMutableData *encryptedData = [[[NSMutableData alloc] init] autorelease]; for (int i=0; i<blockCount; i++) { int bufferSize = MIN(blockSize,[stringBytes length] - i * blockSize); NSData *buffer = [stringBytes subdataWithRange:NSMakeRange(i * blockSize, bufferSize)]; OSStatus status = SecKeyEncrypt(key, kSecPaddingPKCS1, (const uint8_t *)[buffer bytes], [buffer length], cipherBuffer, &cipherBufferSize); if (status == noErr){ NSData *encryptedBytes = [[NSData alloc] initWithBytes:(const void *)cipherBuffer length:cipherBufferSize]; [encryptedData appendData:encryptedBytes]; [encryptedBytes release]; }else{ if (cipherBuffer) free(cipherBuffer); return nil; } } if (cipherBuffer) free(cipherBuffer); //release key CFRelease(key); // NSLog(@"Encrypted text (%d bytes): %@", [encryptedData length], [encryptedData description]); // NSLog(@"Encrypted text base64: %@", [Base64 encode:encryptedData]); return encryptedData; }