=============蘋果自帶方法=====================
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
這是一個大工程,請從工程中尋找相關模塊代碼.