SHA1WithRSA算法加签的实现

最近写自己公司sdk和后台对接的时候,后台给我提供了私钥和公钥,要求参数进行排序拼接后的字符串,进行SHA1WithRSA算法加签,找了一些网站,发现资料首先很少,然后也没有找到根据后台提供的私钥进行算法加签的,最后和后台协商了一下,我这边本地生成java的pem私有公有文件,他那边用我给他的,然后我本地用p12文件进行SHA1WithRSA算法加签,最后完美解决。
先贴一下本地的代码:
.h文件中

#import 

@interface RSAEncryptor : NSObject
+(NSString *)signTheDataSHA1WithRSA:(NSString *)plainText;
@end

.m文件中

#import "RSAEncryptor.h"
#import 
#import 
#import 
#import "Base64Util.h"
#define kChosenDigestLength CC_SHA1_DIGEST_LENGTH
@implementation RSAEncryptor
+(NSString *)signTheDataSHA1WithRSA:(NSString *)plainText
{
    uint8_t* signedBytes = NULL;
    size_t signedBytesSize = 0;
    OSStatus sanityCheck = noErr;
    NSData* signedHash = nil;
    
    NSString * path = [[NSBundle mainBundle]pathForResource:@"private_key" ofType:@"p12"];
    NSData * data = [NSData dataWithContentsOfFile:path];
    NSMutableDictionary * options = [[NSMutableDictionary alloc] init]; // Set the private key query dictionary.
    [options setObject:@"123456" forKey:(id)kSecImportExportPassphrase];
    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
    OSStatus securityError = SecPKCS12Import((CFDataRef) data, (CFDictionaryRef)options, &items);
    if (securityError!=noErr) {
        return nil ;
    }
    CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
    SecIdentityRef identityApp =(SecIdentityRef)CFDictionaryGetValue(identityDict,kSecImportItemIdentity);
    SecKeyRef privateKeyRef=nil;
    SecIdentityCopyPrivateKey(identityApp, &privateKeyRef);
    signedBytesSize = SecKeyGetBlockSize(privateKeyRef);
    
    NSData *plainTextBytes = [plainText dataUsingEncoding:NSUTF8StringEncoding];
    
    signedBytes = malloc( signedBytesSize * sizeof(uint8_t) ); // Malloc a buffer to hold signature.
    memset((void *)signedBytes, 0x0, signedBytesSize);
    
    sanityCheck = SecKeyRawSign(privateKeyRef,
                                kSecPaddingPKCS1SHA1,
                                (const uint8_t *)[[self getHashBytes:plainTextBytes] bytes],
                                kChosenDigestLength,
                                (uint8_t *)signedBytes,
                                &signedBytesSize);
    
    if (sanityCheck == noErr)
    {
        signedHash = [NSData dataWithBytes:(const void *)signedBytes length:(NSUInteger)signedBytesSize];
    }
    else
    {
        return nil;
    }
    
    if (signedBytes)
    {
        free(signedBytes);
    }
    NSString *signatureResult=[NSString stringWithFormat:@"%@",[signedHash base64Encoding]];
    return signatureResult;
}

+ (NSData *)getHashBytes:(NSData *)plainText {
    CC_SHA1_CTX ctx;
    uint8_t * hashBytes = NULL;
    NSData * hash = nil;
    
    // Malloc a buffer to hold hash.
    hashBytes = malloc( kChosenDigestLength * sizeof(uint8_t) );
    memset((void *)hashBytes, 0x0, kChosenDigestLength);
    // Initialize the context.
    CC_SHA1_Init(&ctx);
    // Perform the hash.
    CC_SHA1_Update(&ctx, (void *)[plainText bytes], [plainText length]);
    // Finalize the output.
    CC_SHA1_Final(hashBytes, &ctx);
    
    // Build up the SHA1 blob.
    hash = [NSData dataWithBytes:(const void *)hashBytes length:(NSUInteger)kChosenDigestLength];
    if (hashBytes) free(hashBytes);
    
    return hash;
}

@end

接下来说一下iOS和java的公钥私钥文件的生成。
在iOS中使用RSA加密解密,需要用到.der和.p12后缀格式的文件,其中.der格式的文件存放的是公钥(Public key)用于加密,.p12格式的文件存放的是私钥(Private key)用于解密.
生成环境是在mac系统下,使用openssl进行生成,首先打开终端,按下面这些步骤依次来做:

1.生成模长为1024bit的私钥文件private_key.pem

openssl genrsa -out private_key.pem 1024

2.生成证书请求文件rsaCertReq.csr

openssl req -new -key private_key.pem -out rsaCerReq.csr

注意:这一步会提示输入国家、省份、mail等信息,可以根据实际情况填写,或者全部不用填写,直接全部敲回车.

3.生成证书rsaCert.crt,并设置有效时间为1年

openssl x509 -req -days 3650 -in rsaCerReq.csr -signkey private_key.pem -out rsaCert.crt

4.生成供iOS使用的公钥文件public_key.der

openssl x509 -outform der -in rsaCert.crt -out public_key.der

5.生成供iOS使用的私钥文件private_key.p12

openssl pkcs12 -export -out private_key.p12 -inkey private_key.pem -in rsaCert.crt

注意:这一步会提示给私钥文件设置密码,直接输入想要设置密码即可,然后敲回车,然后再验证刚才设置的密码,再次输入密码,然后敲回车,完毕!
在解密时,private_key.p12文件需要和这里设置的密码配合使用,因此需要牢记此密码

6.生成供Java使用的公钥rsa_public_key.pem

openssl rsa -in private_key.pem -out rsa_public_key.pem -pubout

7.生成供Java使用的私钥pkcs8_private_key.pem

openssl pkcs8 -topk8 -in private_key.pem -out pkcs8_private_key.pem -nocrypt
SHA1WithRSA算法加签的实现_第1张图片
image.png

将java的那两个直接丢给后台,让他们用这个,他们可以用notepad直接打开获取到~
搞定~

你可能感兴趣的:(SHA1WithRSA算法加签的实现)