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)创建证书请求(按照提示输入信息)

openssl req -new -out cert.csr -key private_key.pem

2)自签署根证书

openssl x509 -req -in cert.csr -out public_key.der -outform der -signkey private_key.pem -days 3650

2.验证证书。把public_key.der拖到xcode中,如果文件没有问题的话,那么就可以直接在xcode中打开,看到证书的各种信息。

 

也可以一行搞定!

最简单快捷的方法,打开Terminal,使用openssl(Mac OS X自带)生成私钥和自签名的x509证书。

openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem -days 3650

按照命令行的提示输入内容就行了。

几个说明:

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;
}

 

posted @ 2015-04-28 17:52  superchao  阅读(3146)  评论(1编辑  收藏  举报