iOS使用MIHCrypto進行RSA私鑰加密公鑰解密

最近公司項目有個需求,在客戶端實現(xiàn)利用私鑰進行RSA加密,公鑰進行解密的需求。之前做過的都是公鑰加密私鑰解密,而且也在別人的文章中看到過不建議用私鑰做加密,不過公司需求如此,只能硬著頭皮上了。

經(jīng)過初步排查,基本確定了iOS源生框架是沒有提供相應的API接口的,只有常規(guī)的公鑰加密私鑰解密。于是開始Google,看了N多文章和問答,鎖定了OpenSSL庫可以實現(xiàn)這個需求,不過這個是C寫的,用起來稍微麻煩點,于是又順藤摸瓜找到了MIHCrypto這個庫,有兩個注意的地方記錄如下:

  1. 如果使用密鑰串來進行加密解密,在傳遞 私鑰給MIHCrypto時,要在首尾添加-----BEGIN RSA PRIVATE KEY-----\n和\n-----END RSA PRIVATE KEY-----,公鑰不需要,庫中會自行添加。如果是使用證書來加密解密,則要在傳遞公鑰時去掉首尾的-----BEGIN PUBLIC KEY-----\n和\n-----END PUBLIC KEY-----,不然會拋異常。
  2. MIHRSAPublicKey在初始化時采用了MIH_base64EncodedStringWithWrapWidth:的方法來處理傳過來的data,之前解密一直不成功就是因為這個導致的,替換成常規(guī)方法[[NSStringalloc]initWithData:dataValueencoding:NSUTF8StringEncoding]就解密成功了。

代碼

@interface CCRSAUtil :NSObject

/**

初始化方法

@param privateKey 私鑰

@param publicKey 公鑰

@return RSA加密工具實例

*/

- (instancetype)initWithPrivate:(NSString*)privateKey public:(NSString*)publicKey;

/**

私鑰加密

@param string 需要加密的字符串

@return 加密后經(jīng)過Base64編碼的字符串

*/

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

/**

公鑰解密

@param encryptString 經(jīng)過私鑰加密的字符串

@return 解密后的明文

*/

- (NSString*)publicDecrypt:(NSString*)encryptString;

@end
@interface CCRSAUtil()

@property(strong,nonatomic)MIHKeyPair*keyPair;

@end

@implementationCCRSAUtil

- (instancetype)initWithPrivate:(NSString *)privateKey public:(NSString *)publicKey {
    self = [super init];
    if (self) {
        if (![privateKey hasPrefix:@"-----BEGIN RSA PRIVATE KEY-----"]) {
            privateKey = [@"-----BEGIN RSA PRIVATE KEY-----\n" stringByAppendingString:privateKey];
            privateKey = [privateKey stringByAppendingString:@"\n-----END RSA PRIVATE KEY-----"];
        }
        MIHKeyPair *keyPair = [[MIHKeyPair alloc] init];
        MIHRSAPrivateKey *rsaPrivate =  [[MIHRSAPrivateKey alloc] initWithData:[privateKey dataUsingEncoding:NSUTF8StringEncoding]];
        rsaPrivate.rsaPadding = RSA_PKCS1_PADDING;
        keyPair.private = rsaPrivate;
        MIHRSAPublicKey *rsaPublic = [[MIHRSAPublicKey alloc] initWithData:[publicKey dataUsingEncoding:NSUTF8StringEncoding]];
        rsaPublic.rsaPadding = RSA_PKCS1_PADDING;
        keyPair.public = rsaPublic;
        self.keyPair = keyPair;        
    }
    return self;
}

#pragma mark -

- (NSString *)privateEncryptWithString:(NSString *)string {
    //私鑰加密
    NSError *signingError = nil;
    NSData *message = [string dataUsingEncoding:NSUTF8StringEncoding];// load something to sign from somewhere
    
    NSData *signature = [self.keyPair.private encrypt:message error:&signingError];
    if (signingError == nil) {
        return [signature MIH_base64EncodedString];
    }
    return nil;
}

- (NSString *)publicDecrypt:(NSString *)encryptString {
    //公鑰解密
    //*******注意,如果從證書讀取公鑰,要去掉證書本身自帶的頭和尾字符*******
    NSError *signingError = nil;
    NSData *message = [NSData MIH_dataByBase64DecodingString:encryptString];// load something to sign from somewhere
    
    NSData *signature = [self.keyPair.public decrypt:message error:&signingError];
    if (signingError == nil) {
        return [[NSString alloc] initWithData:signature encoding:NSUTF8StringEncoding];
    }
    return nil;
}

@end

MIHCrypto支持Cocoapods導入,我fork的一份,把data處理改了一下,需要的同學可以直接使用

pod'MIHCrypto', :podspec =>'https://raw.githubusercontent.com/lw254605953/MIHCrypto/master/MIHCrypto.podspec'
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容