iOS端Sha1RSA加签实现

该文详细介绍了在iOS平台上使用SHA1和RSA算法进行加签和验签的流程,包括加签的两步过程(SHA1摘要,RSA私钥加密)以及验签的步骤。同时提供了具体的代码实现,包括添加私钥和公钥到系统密钥链,以及加签和验签的函数。
摘要由CSDN通过智能技术生成

目录

1、实现原理

1、加签流程

2、验签流程

 2、代码实现

1、 SHA1RSAUtil

2、使用


1、实现原理

1、加签流程

第一步:对明文进行SHA1算法,生成数据摘要

第二步:使用RSA私钥对摘要内容进行加签操作,生成签名

2、验签流程

 2、代码实现

1、 SHA1RSAUtil

#import "SHA1RSAUtil.h"
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
#import <Security/Security.h>


@implementation SHA1RSAUtil
#pragma mark - 添加私钥
+ (SecKeyRef)addPrivateKey:(NSString *)key{
  // This is a base64 encoded key. so, decode it.
  NSData *data = [[NSData alloc] initWithBase64EncodedString:key options:NSDataBase64DecodingIgnoreUnknownCharacters];
  
  if(!data){ return nil; }
  //a tag to read/write keychain storage
  NSString *tag = @"RSA_PRIVATE_KEY";
  NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]];
  
  // Delete any old lingering key with the same tag
  NSMutableDictionary *privateKey = [[NSMutableDictionary alloc] init];
  [privateKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass];
  [privateKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
  [privateKey setObject:d_tag forKey:(__bridge id)kSecAttrApplicationTag];
  SecItemDelete((__bridge CFDictionaryRef)privateKey);
  
  // Add persistent version of the key to system keychain
  [privateKey setObject:data forKey:(__bridge id)kSecValueData];
  [privateKey setObject:(__bridge id) kSecAttrKeyClassPrivate forKey:(__bridge id)kSecAttrKeyClass];
  [privateKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnPersistentRef];
  
  CFTypeRef persistKey = nil;
  OSStatus status = SecItemAdd((__bridge CFDictionaryRef)privateKey, &persistKey);
  if (persistKey != nil){ CFRelease(persistKey); }
  if ((status != noErr) && (status != errSecDuplicateItem)) { return nil; }
  
  [privateKey removeObjectForKey:(__bridge id)kSecValueData];
  [privateKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef];
  [privateKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
  [privateKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
  
  // Now fetch the SecKeyRef version of the key
  SecKeyRef keyRef = nil;
  status = SecItemCopyMatching((__bridge CFDictionaryRef)privateKey, (CFTypeRef *)&keyRef);
  if(status != noErr){
    return nil;
  }
  return keyRef;
}


#pragma mark - 添加公钥
+ (SecKeyRef)addPublicKey:(NSString *)pubKey{
  NSData *data = [[NSData alloc] initWithBase64EncodedString:pubKey options:NSDataBase64DecodingIgnoreUnknownCharacters];
  
  //a tag to read/write keychain storage
  NSString *tag = @"RSA_PUBLIC_KEY";
  NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]];
  
  // Delete any old lingering key with the same tag
  NSMutableDictionary *publicKey = [[NSMutableDictionary alloc] init];
  [publicKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass];
  [publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
  [publicKey setObject:d_tag forKey:(__bridge id)kSecAttrApplicationTag];
  SecItemDelete((__bridge CFDictionaryRef)publicKey);
  
  // Add persistent version of the key to system keychain
  [publicKey setObject:data forKey:(__bridge id)kSecValueData];
  [publicKey setObject:(__bridge id) kSecAttrKeyClassPublic forKey:(__bridge id)kSecAttrKeyClass];
  [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnPersistentRef];
  
  CFTypeRef persistKey = nil;
  OSStatus status = SecItemAdd((__bridge CFDictionaryRef)publicKey, &persistKey);
  if (persistKey != nil){
    CFRelease(persistKey);
  }
  
  if ((status != noErr) && (status != errSecDuplicateItem)) { return nil; }
  
  [publicKey removeObjectForKey:(__bridge id)kSecValueData];
  [publicKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef];
  [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
  [publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
  
  // Now fetch the SecKeyRef version of the key
  SecKeyRef keyRef = nil;
  status = SecItemCopyMatching((__bridge CFDictionaryRef)publicKey, (CFTypeRef *)&keyRef);
  if(status != noErr){
    return nil;
  }
  return keyRef;
}





#pragma mark - sha1生成摘要
// digest message with sha1
+ (NSData *)sha1:(NSString *)str
{
  const void *data = [str cStringUsingEncoding:NSUTF8StringEncoding];
  CC_LONG len = (CC_LONG)strlen(data);
  uint8_t * md = malloc( CC_SHA1_DIGEST_LENGTH * sizeof(uint8_t) );;
  CC_SHA1(data, len, md);
  return [NSData dataWithBytes:md length:CC_SHA1_DIGEST_LENGTH];
}

#pragma mark - 使用sha1rsa生成验签
+ (NSString *)signSHA1WithRSA:(NSString *)content
                   privateKey:(NSString *)key{
  
  SecKeyRef privateKeyRef = [self addPrivateKey:key];
  if (!privateKeyRef) {
    NSLog(@"添加私钥失败");
    return  nil;
  }
  
  NSData *sha1Data = [self sha1:content];
  uint8_t *sig = NULL;
  size_t sig_len = 0;
  sig_len = SecKeyGetBlockSize(privateKeyRef);
  sig = malloc(sig_len * sizeof(uint8_t));
  memset((void *) sig, 0x0, sig_len);
  
  OSStatus status = SecKeyRawSign(
                                  privateKeyRef,
                                  kSecPaddingPKCS1SHA1,
                                  [sha1Data bytes],
                                  CC_SHA1_DIGEST_LENGTH,
                                  sig,
                                  &sig_len
                                  );
  if (status != noErr) {
    NSLog(@"加签失败:%d",(int)status); return nil;
  }
  NSData *outData = [NSData dataWithBytes:sig length:sig_len];
  NSString * base64String = [outData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
  
  if (sig) {
      free(sig);
  }
  
  return base64String;
}

#pragma mark - 使用公钥验签
+ (BOOL)verifySHA1WithRSA:(NSString *)content
                signature:(NSString *)signature
                publicKey:(NSString *)key{
  SecKeyRef publicKeyRef = [self addPublicKey:key];
  if (!publicKeyRef) { NSLog(@"添加公钥失败"); return NO; }
  NSData *originData = [self sha1:content];
  NSData *signatureData = [[NSData alloc] initWithBase64EncodedString:signature options:NSDataBase64DecodingIgnoreUnknownCharacters];
  if (!originData || !signatureData) { return NO; }
  OSStatus status =  SecKeyRawVerify(publicKeyRef, kSecPaddingPKCS1SHA1, [originData bytes], originData.length, [signatureData bytes], signatureData.length);
  
  if (status ==noErr) {
    return  YES;
  }
  else{
    NSLog(@"验签失败:%d",status);
    return NO;
  }
}

2、使用

  //加签
  NSData *encodeData = [tempStr dataUsingEncoding:NSUTF8StringEncoding];
  NSString *base64String = [encodeData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
  NSString *sign =  [SHA1RSAUtil signSHA1WithRSA:base64String privateKey:privateKey];
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pdw11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值