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

本文介绍了一种在iOS应用中使用RSA加密算法的方法。通过Objective-C语言实现了公钥和私钥的导入,并提供了字符串加密、解密及签名验证等功能。文章详细展示了如何利用OpenSSL库完成这些操作。
摘要由CSDN通过智能技术生成

一 .下载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:keyStringandKeytype:type];

    BOOL writeSuccess = [formatRSAKeyStringwriteToFile:rsaFilePathatomically: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验证签名

    //signStringbase64字符串

- (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 *)[signatureDatabytes];

    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 *)[signatureDatabytes];

    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:siglength: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:siglength: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:encDatalength: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*)[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;

    

    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 < [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-----"];

       

    }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:strwithSign:resign];

    

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






如果报错找不到Openssl 请在Build Settings——Hearder search Paths中配置其地址
导入文件 libcrypto.a  与 libssl.a

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值