=============苹果自带方法=====================
typedef void (^keyPair)(SecKeyRef publicKey ,SecKeyRef privateKey);
#pragma mark - =============苹果自带方法=====================
+ (void)getRSAKeyPairWithKeySize:(int)keySize keyPair:(keyPair)pair;
{
OSStatus status = noErr;
if (keySize == 512 || keySize == 1024 || keySize == 2048) {
//定义dictionary,用于传递SecKeyGeneratePair函数中的第1个参数。
NSMutableDictionary *privateKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary *publicKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary *keyPairAttr = [[NSMutableDictionary alloc] init];
//把第1步中定义的字符串转换为NSData对象。
NSData * publicTag = [NSData dataWithBytes:publicKeyIdentifier
length:strlen((const char *)publicKeyIdentifier)];
NSData * privateTag = [NSData dataWithBytes:privateKeyIdentifier
length:strlen((const char *)privateKeyIdentifier)];
//为公/私钥对准备SecKeyRef对象。
SecKeyRef publicKey = NULL;
SecKeyRef privateKey = NULL;
//
//设置密钥对的密钥类型为RSA。
[keyPairAttr setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
//设置密钥对的密钥长度为1024。
[keyPairAttr setObject:[NSNumber numberWithInt:keySize] forKey:(id)kSecAttrKeySizeInBits];
//设置私钥的持久化属性(即是否存入钥匙串)为YES。
[privateKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecAttrIsPermanent];
[privateKeyAttr setObject:privateTag forKey:(id)kSecAttrApplicationTag];
//设置公钥的持久化属性(即是否存入钥匙串)为YES。
[publicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecAttrIsPermanent];
[publicKeyAttr setObject:publicTag forKey:(id)kSecAttrApplicationTag];
// 把私钥的属性集(dictionary)加到密钥对的属性集(dictionary)中。
[keyPairAttr setObject:privateKeyAttr forKey:(id)kSecPrivateKeyAttrs];
[keyPairAttr setObject:publicKeyAttr forKey:(id)kSecPublicKeyAttrs];
//生成密钥对
status = SecKeyGeneratePair((CFDictionaryRef)keyPairAttr,&publicKey, &privateKey); // 13
if (status == noErr && publicKey != NULL && privateKey != NULL) {
pair(publicKey,privateKey);
}
else
pair(publicKey,privateKey);
}
}
==============OpenSSL 方式=================
#pragma mark - ==============OpenSSL 方式=================
#pragma mark ---生成密钥对
+ (BOOL)generateRSAKeyPairWithKeySize:(int)keySize publicKey:(RSA **)publicKey privateKey:(RSA **)privateKey {
if (keySize == 512 || keySize == 1024 || keySize == 2048) {
/* 产生RSA密钥 */
RSA *rsa = RSA_new();
BIGNUM* e = BN_new();
/* 设置随机数长度 */
BN_set_word(e, 65537);
/* 生成RSA密钥对 */
RSA_generate_key_ex(rsa, keySize, e, NULL);
if (rsa) {
*publicKey = RSAPublicKey_dup(rsa);
*privateKey = RSAPrivateKey_dup(rsa);
return YES;
}
}
return NO;
}
#pragma mark ---RSA 转化为字符串
+ (NSString *)PEMFormatRSAKey:(RSA *)rsaKey isPublic:(BOOL)isPublickey
{
if (!rsaKey) {
return nil;
}
BIO *bio = BIO_new(BIO_s_mem());
if (isPublickey)
PEM_write_bio_RSA_PUBKEY(bio, rsaKey);
else
{
//此方法生成的是pkcs1格式的,IOS中需要pkcs8格式的,因此通过PEM_write_bio_PrivateKey 方法生成
// PEM_write_bio_RSAPrivateKey(bio, rsaKey, NULL, NULL, 0, NULL, NULL);
EVP_PKEY* key = NULL;
key = EVP_PKEY_new();
EVP_PKEY_assign_RSA(key, rsaKey);
PEM_write_bio_PrivateKey(bio, key, NULL, NULL, 0, NULL, NULL);
}
BUF_MEM *bptr;
BIO_get_mem_ptr(bio, &bptr);
BIO_set_close(bio, BIO_NOCLOSE); /* So BIO_free() leaves BUF_MEM alone */
BIO_free(bio);
return [NSString stringWithUTF8String:bptr->data];
}
注意:
openssl 生成的私钥为 pkcs1格式的,我们加密需要的是 pkcs8格式的,暂时还没有找到转换方法.
更新:
//此方法生成的是pkcs1格式的,IOS中需要pkcs8格式的
PEM_write_bio_RSAPrivateKey(bio, rsaKey, NULL, NULL, 0, NULL, NULL);
因此通过PEM_write_bio_PrivateKey 方法生成
EVP_PKEY* key = NULL;
key = EVP_PKEY_new();
EVP_PKEY_assign_RSA(key, rsaKey);
PEM_write_bio_PrivateKey(bio, key, NULL, NULL, 0, NULL, NULL);
Demo地址:https://github.com/yuying2012/WJDStudyLibrary
这是一个大工程,请从工程中寻找相关模块代码.