1. 程式人生 > >RSA用祕鑰簽名與驗籤 加密解密

RSA用祕鑰簽名與驗籤 加密解密

一 .下載openssl檔案 匯入

二.新建類程式碼如下

#import <Foundation/Foundation.h>

typedefenum {

    KeyTypePublic = 0,

    KeyTypePrivate

}KeyType;

@interface HBRSAHandler : NSObject

- (BOOL)importKeyWithType:(KeyType)type andPath:(NSString*)path;

- (BOOL)importKeyWithType:(KeyType)type andkeyString:(NSString *)keyString;

//驗證簽名

Sha1 + RSA

- (BOOL)verifyString:(NSString *)string withSign:(NSString *)signString;

//驗證簽名 md5 + RSA

- (BOOL)verifyMD5String:(NSString *)string withSign:(NSString *)signString;

- (NSString *)signString:(NSString *)string;

- (NSString *)signMD5String:(NSString *)string;

- (NSString *) encryptWithPublicKey:(

NSString*)content;

- (NSString *) decryptWithPrivatecKey:(NSString*)content;

@end

#import "HBRSAHandler.h"

#include <openssl/rsa.h>

#include <openssl/pem.h>

#include <openssl/err.h>

#include <openssl/md5.h>

typedefenum {

    RSA_PADDING_TYPE_NONE       = RSA_NO_PADDING,

    RSA_PADDING_TYPE_PKCS1      =

RSA_PKCS1_PADDING,

    RSA_PADDING_TYPE_SSLV23     = RSA_SSLV23_PADDING

}RSA_PADDING_TYPE;

#define  PADDING   RSA_PADDING_TYPE_PKCS1

@implementation HBRSAHandler

{

RSA* _rsa_pub;

RSA* _rsa_pri;

}

#pragma mark - public methord

-(BOOL)importKeyWithType:(KeyType)type andPath:(NSString *)path

{

BOOL status = NO;

constchar* cPath = [pathcStringUsingEncoding:NSUTF8StringEncoding];

FILE* file = fopen(cPath, "rb");

if (!file) {

return status;

    }

if (type == KeyTypePublic) {

_rsa_pub = NULL;

if((_rsa_pub =PEM_read_RSA_PUBKEY(file,NULL,NULL,NULL))){

            status = YES;

        }

    }elseif(type ==KeyTypePrivate){

_rsa_pri = NULL;

if ((_rsa_pri =PEM_read_RSAPrivateKey(file,NULL,NULL,NULL))) {

            status = YES;

        }

    }

fclose(file);

return status;

}

- (BOOL)importKeyWithType:(KeyType)type andkeyString:(NSString *)keyString

{

if (!keyString) {

returnNO;

    }

BOOL status = NO;

BIO *bio = NULL;

RSA *rsa = NULL;

    bio = BIO_new(BIO_s_file());

NSString* temPath =NSTemporaryDirectory();

NSString* rsaFilePath = [temPathstringByAppendingPathComponent:@"RSAKEY"];

NSString* formatRSAKeyString = [selfformatRSAKeyWithKeyString:keyStringandKeytype:type];

BOOL writeSuccess = [formatRSAKeyStringwriteToFile:rsaFilePathatomically:YESencoding:NSUTF8StringEncodingerror:nil];

if (!writeSuccess) {

returnNO;

    }

constchar* cPath = [rsaFilePathcStringUsingEncoding:NSUTF8StringEncoding];

BIO_read_filename(bio, cPath);

if (type == KeyTypePrivate) {

        rsa = PEM_read_bio_RSAPrivateKey(bio,NULL,NULL,"");

_rsa_pri = rsa;

if (rsa != NULL && 1 ==RSA_check_key(rsa)) {

            status = YES;

        } else {

            status = NO;

        }

    }

else{

        rsa = PEM_read_bio_RSA_PUBKEY(bio,NULL,NULL,NULL);

_rsa_pub = rsa;

if (rsa != NULL) {

            status = YES;

        } else {

            status = NO;

        }

    }

BIO_free_all(bio);

    [[NSFileManagerdefaultManager] removeItemAtPath:rsaFilePatherror:nil];

return status;

}

#pragma mark RSA sha1驗證簽名

//signStringbase64字串

- (BOOL)verifyString:(NSString *)string withSign:(NSString *)signString

{

if (!_rsa_pub) {

NSLog(@"please import public key first");

returnNO;

    }

constchar *message = [stringcStringUsingEncoding:NSUTF8StringEncoding];

int messageLength = (int)[stringlengthOfBytesUsingEncoding:NSUTF8StringEncoding];

NSData *signatureData = [[NSDataalloc]initWithBase64EncodedString:signStringoptions:0];

unsignedchar *sig = (unsignedchar *)[signatureDatabytes];

unsignedint sig_len = (int)[signatureDatalength];

unsignedchar sha1[20];

SHA1((unsignedchar *)message, messageLength, sha1);

int verify_ok =RSA_verify(NID_sha1

                                      , sha1, 20

                                      , sig, sig_len

                                      , _rsa_pub);

if (1 == verify_ok){

returnYES;

    }

returnNO;

}

#pragma mark RSA MD5 驗證簽名

- (BOOL)verifyMD5String:(NSString *)string withSign:(NSString *)signString

{

if (!_rsa_pub) {

NSLog(@"please import public key first");

returnNO;

    }

constchar *message = [stringcStringUsingEncoding:NSUTF8StringEncoding];

// int messageLength = (int)[string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];

NSData *signatureData = [[NSDataalloc]initWithBase64EncodedString:signStringoptions:0];

unsignedchar *sig = (unsignedchar *)[signatureDatabytes];

unsignedint sig_len = (int)[signatureDatalength];

unsignedchar digest[MD5_DIGEST_LENGTH];

MD5_CTX ctx;

MD5_Init(&ctx);

MD5_Update(&ctx, message,strlen(message));

MD5_Final(digest, &ctx);

int verify_ok = RSA_verify(NID_md5

                                      , digest, MD5_DIGEST_LENGTH

                                      , sig, sig_len

                                      , _rsa_pub);

if (1 == verify_ok){

returnYES;

    }

returnNO;

}

- (NSString *)signString:(NSString *)string

{

if (!_rsa_pri) {

NSLog(@"please import private key first");

returnnil;

    }

constchar *message = [stringcStringUsingEncoding:NSUTF8StringEncoding];

int messageLength = (int)strlen(message);

unsignedchar *sig = (unsignedchar *)malloc(256);

unsignedint sig_len;

unsignedchar sha1[20];

SHA1((unsignedchar *)message, messageLength, sha1);

int rsa_sign_valid =RSA_sign(NID_sha1

                                          , sha1, 20

                                          , sig, &sig_len

                                          , _rsa_pri);

if (rsa_sign_valid ==1) {

NSData* data = [NSDatadataWithBytes:siglength:sig_len];

NSString * base64String = [database64EncodedStringWithOptions:0];

free(sig);

return base64String;

    }

free(sig);

returnnil;

}

- (NSString *)signMD5String:(NSString *)string

{

if (!_rsa_pri) {

NSLog(@"please import private key first");

returnnil;

    }

constchar *message = [stringcStringUsingEncoding:NSUTF8StringEncoding];

//int messageLength = (int)strlen(message);

unsignedchar *sig = (unsignedchar *)malloc(256);

unsignedint sig_len;

unsignedchar digest[MD5_DIGEST_LENGTH];

MD5_CTX ctx;

MD5_Init(&ctx);

MD5_Update(&ctx, message,strlen(message));

MD5_Final(digest, &ctx);

int rsa_sign_valid =RSA_sign(NID_md5

                                  , digest, MD5_DIGEST_LENGTH

                                  , sig, &sig_len

                                  , _rsa_pri);

if (rsa_sign_valid ==1) {

NSData* data = [NSDatadataWithBytes:siglength:sig_len];

NSString * base64String = [database64EncodedStringWithOptions:0];

free(sig);

return base64String;

    }

free(sig);

returnnil;

}

- (NSString *) encryptWithPublicKey:(NSString*)content

{

if (!_rsa_pub) {

NSLog(@"please import public key first");

returnnil;

    }

int status;

int length  = (int)[contentlength];

unsignedchar input[length +1];

bzero(input, length +1);

int i = 0;

for (; i < length; i++)

        {

        input[i] = [content characterAtIndex:i];

        }

NSInteger  flen = [selfgetBlockSizeWithRSA_PADDING_TYPE:PADDINGandRSA:_rsa_pub];

char *encData = (char*)malloc(flen);

bzero(encData, flen);

    status = RSA_public_encrypt(length, (unsignedchar*)input, (unsignedchar*)encData,_rsa_pub,PADDING);

if (status){

NSData *returnData = [NSDatadataWithBytes:encDatalength:status];

free(encData);

        encData = NULL;

//NSString *ret = [returnData base64EncodedString];

NSString *ret = [returnDatabase64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

return ret;

        }

free(encData);

    encData = NULL;

returnnil;

}

- (NSString *) decryptWithPrivatecKey:(NSString*)content

{

if (!_rsa_pri) {

NSLog(@"please import private key first");

returnnil;

    }    int status;

//NSData *data = [content base64DecodedData];

NSData *data = [[NSDataalloc]initWithBase64EncodedString:contentoptions:NSDataBase64DecodingIgnoreUnknownCharacters];

int length = (int)[datalength];

NSInteger flen = [selfgetBlockSizeWithRSA_PADDING_TYPE:PADDINGandRSA:_rsa_pri];

char *decData = (char*)malloc(flen);

bzero(decData, flen);

    status = RSA_private_decrypt(length, (unsignedchar*)[databytes], (unsignedchar*)decData,_rsa_pri,PADDING);

if (status)

        {

NSMutableString *decryptString = [[NSMutableStringalloc]initWithBytes:decDatalength:strlen(decData)encoding:NSASCIIStringEncoding];

free(decData);

        decData = NULL;

return decryptString;

        }

free(decData);

    decData = NULL;

returnnil;

}

- (int)getBlockSizeWithRSA_PADDING_TYPE:(RSA_PADDING_TYPE)padding_type andRSA:(RSA*)rsa

{

int len = RSA_size(rsa);

if (padding_type ==RSA_PADDING_TYPE_PKCS1 || padding_type ==RSA_PADDING_TYPE_SSLV23) {

        len -= 11;

    }

return len;

}

-(NSString*)formatRSAKeyWithKeyString:(NSString*)keyString andKeytype:(KeyType)type

{

NSInteger lineNum = -1;

NSMutableString *result = [NSMutableStringstring];

if (type == KeyTypePrivate) {

        [result appendString:@"-----BEGIN PRIVATE KEY-----\n"];

        lineNum = 79;

    }elseif(type ==KeyTypePublic){

    [result appendString:@"-----BEGIN PUBLIC KEY-----\n"];

         lineNum = 76;

    }

int count = 0;

for (int i =0; i < [keyStringlength]; ++i) {

unichar c = [keyStringcharacterAtIndex:i];

if (c == '\n' || c == '\r') {

continue;

        }

        [result appendFormat:@"%c", c];

if (++count == lineNum) {

            [result appendString:@"\n"];

            count = 0;

        }

    }

if (type == KeyTypePrivate) {

        [result appendString:@"\n-----END PRIVATE KEY-----"];

    }elseif(type ==KeyTypePublic){

        [result appendString:@"\n-----END PUBLIC KEY-----"];

    }

return result;

}

@end


實現:

   NSString *str=@"hdshgj";

NSString *publicKeyFilePath = [[NSBundlemainBundle]pathForResource:@"public_key.pem"ofType:nil];

NSString *privateKeyFilePath = [[NSBundlemainBundle]pathForResource:@"private_key.pem"ofType:nil];

HBRSAHandler* handler = [HBRSAHandlernew];

    [handler importKeyWithType:KeyTypePublicandPath:publicKeyFilePath];

    [handler importKeyWithType:KeyTypePrivateandPath:privateKeyFilePath];

NSString* result = [handlerencryptWithPublicKey:str];

NSLog(@"加密%@",result);

NSString* resign = [handlersignString:str];

NSLog(@"簽名%@",resign);

NSString* result2 = [handlerdecryptWithPrivatecKey:result];

NSLog(@"解密%@",result2);

BOOL result3 = [handlerverifyString:strwithSign:resign];

NSLog(@"驗證簽名結果%@",[NSStringstringWithFormat:@"驗證簽名結果(1成功,0失敗) %d",result3]);


如果報錯找不到Openssl 請在Build Settings——Hearder search Paths中配置其地址匯入檔案 libcrypto.a  與 libssl.a