您的位置:首页 > 其它

RSA用秘钥签名与验签 加密解密

2016-07-05 09:53 549 查看
一 .下载openssl文件 导入

二.新建类代码如下

#import <Foundation/Foundation.h>

typedef enum {

    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>

typedef enum {

    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;

    const char* 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;

        }

        

        

    }else if(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) {

        return
NO;

    }

    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:keyString
andKeytype:type];

    BOOL writeSuccess = [formatRSAKeyStringwriteToFile:rsaFilePath
atomically:YESencoding:NSUTF8StringEncodingerror:nil];

    if (!writeSuccess) {

        return
NO;

    }

    const char* 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);

    [[NSFileManager
defaultManager] removeItemAtPath:rsaFilePatherror:nil];

    return status;

}

#pragma mark RSA sha1验证签名

    //signString为base64字符串

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

{

    if (!_rsa_pub) {

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

        return
NO;

    }

    const char *message = [stringcStringUsingEncoding:NSUTF8StringEncoding];

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

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

    unsigned char *sig = (unsignedchar *)[signatureData
bytes];

    unsigned int sig_len = (int)[signatureDatalength];

    

    

   

    unsigned char 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){

        return  
YES;

    }

    return NO;

    

    

}

#pragma mark RSA MD5 验证签名

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

{

    if (!_rsa_pub) {

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

        return
NO;

    }

    const char *message = [stringcStringUsingEncoding:NSUTF8StringEncoding];

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

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

    unsigned char *sig = (unsignedchar *)[signatureData
bytes];

    unsigned int sig_len = (int)[signatureDatalength];

    

    unsigned char 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){

        return  
YES;

    }

    return NO;

    

}

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

{

    if (!_rsa_pri) {

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

        return
nil;

    }

    const char *message = [stringcStringUsingEncoding:NSUTF8StringEncoding];

    int messageLength = (int)strlen(message);

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

    unsigned int sig_len;

    

    unsigned char 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:sig
length:sig_len];

        

        NSString * base64String = [database64EncodedStringWithOptions:0];

        free(sig);

        return base64String;

    }

    

    free(sig);

    return nil;

}

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

{

    if (!_rsa_pri) {

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

        return
nil;

    }

    const char *message = [stringcStringUsingEncoding:NSUTF8StringEncoding];

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

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

    unsigned int sig_len;

    

    unsigned char 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:sig
length:sig_len];

        

        NSString * base64String = [database64EncodedStringWithOptions:0];

        free(sig);

        return base64String;

    }

    

    free(sig);

    return nil;

    

}

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

{

    if (!_rsa_pub) {

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

        return
nil;

    }

    int status;

    int length  = (int)[contentlength];

    unsigned char 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:encData
length:status];

        free(encData);

        encData = NULL;

        

            //NSString *ret = [returnData base64EncodedString];

        NSString *ret = [returnDatabase64EncodedStringWithOptions:
NSDataBase64Encoding64CharacterLineLength];

        return ret;

        }

    

    free(encData);

    encData = NULL;

    

    return nil;

}

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

{

    if (!_rsa_pri) {

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

        return
nil;

    }    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*)[data
bytes], (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;

    

    return nil;

}

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

    }else if(type ==KeyTypePublic){

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

         lineNum = 76;

    }

   

    int count =
0;

    for (int i =0; i < [keyString
length]; ++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-----"];

       

    }else if(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:str
withSign:resign];

    

 NSLog(@"验证签名结果%@",[NSStringstringWithFormat:@"验证签名结果(1成功,0失败):
%d",result3]);

如果报错找不到Openssl 请在Build Settings——Hearder search Paths中配置其地址
导入文件 lib crypto.a  与 libel.a
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息