问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何在IOS中使用RSA加密,能够与.NET的服务器互通

发布网友 发布时间:2022-04-22 09:37

我来回答

1个回答

热心网友 时间:2023-10-04 04:29

  最近几天折腾了一下如何在iOS上使用RSA来加密。iOS上并没有直接的RSA加密API。但是iOS提供了x509的API,而x509是支持RSA加密的。因此,我们可以通过制作自签名的x509证书(由于对安全性要求不高,我们并不需要使用CA认证的证书),再调用x509的相关API来进行加密。接下来记录一下整个流程。
  第一步,制作自签名的证书
  1.最简单快捷的方法,打开Terminal,使用openssl(Mac OS X自带)生成私钥和自签名的x509证书。
  openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem -days 3650
  按照命令行的提示输入内容就行了。
  几个说明:
  public_key.der是输出的自签名的x509证书,即我们要用的。
  private_key.pem是输出的私钥,用来解密的,请妥善保管。
  rsa:1024这里的1024是密钥长度,1024是比较安全的,如果需要更安全的话,可以用2048,但是加解密代价也会增加。
  -days:证书过期时间,一定要加上这个参数,默认的证书过期时间是30天,一般我们不希望证书这么短就过期,所以写上比较合适的天数,例如这里的3650(10年)。
  事实上,这一行命令包含了好几个步骤(我研究下面这些步骤的原因是我手头已经由一个private_key.pem私钥了,想直接用这个来生成x509证书,也就是用到了下面的2-3)
  1)创建私钥
  openssl genrsa -out private_key.pem 1024
  2)创建证书请求(按照提示输入信息)
  openssl req -new -out cert.csr -key private_key.pem
  3)自签署根证书
  openssl x509 -req -in cert.csr -out public_key.der -outform der -signkey private_key.pem -days 3650
  2.验证证书。把public_key.der拖到xcode中,如果文件没有问题的话,那么就可以直接在xcode中打开,看到证书的各种信息。

  第二步,使用public_key.der来进行加密。
  1.导入Security.framework。
  2.把public_key.der放到mainBundle中(一般直接拖到Xcode就行啦)。
  3.从public_key.der读取公钥。
  4.加密。
  下面是参考代码(只能用于加密长度小于等于116字节的内容,适合于对密码进行加密。使用了ARC,不过还是要注意部分资源需要使用CFRealse来释放)
  RSA.h
  //
  // RSA.h
  //
  #import <Foundation/Foundation.h>

  @interface RSA : NSObject {
  SecKeyRef publicKey;
  SecCertificateRef certificate;
  SecPolicyRef policy;
  SecTrustRef trust;
  size_t maxPlainLen;
  }

  - (NSData *) encryptWithData:(NSData *)content;
  - (NSData *) encryptWithString:(NSString *)content;

  @end

  RSA.m
  //
  // RSA.m
  //
  #import "RSA.h"

  @implementation RSA

  - (id)init {
  self = [super init];
  
  NSString *publicKeyPath = [[NSBundle mainBundle] pathForResource:@"public_key"
  ofType:@"der"];
  if (publicKeyPath == nil) {
  NSLog(@"Can not find pub.der");
  return nil;
  }
  
  NSDate *publicKeyFileContent = [NSData dataWithContentsOfFile:publicKeyPath];
  if (publicKeyFileContent == nil) {
  NSLog(@"Can not read from pub.der");
  return nil;
  }
  
  certificate = SecCertificateCreateWithData(kCFAllocatorDefault, ( __bridge CFDataRef)publicKeyFileContent);
  if (certificate == nil) {
  NSLog(@"Can not read certificate from pub.der");
  return nil;
  }
  
  policy = SecPolicyCreateBasicX509();
  OSStatus returnCode = SecTrustCreateWithCertificates(certificate, policy, &trust);
  if (returnCode != 0) {
  NSLog(@"SecTrustCreateWithCertificates fail. Error Code: %ld", returnCode);
  return nil;
  }
  
  SecTrustResultType trustResultType;
  returnCode = SecTrustEvaluate(trust, &trustResultType);
  if (returnCode != 0) {
  NSLog(@"SecTrustEvaluate fail. Error Code: %ld", returnCode);
  return nil;
  }
  
  publicKey = SecTrustCopyPublicKey(trust);
  if (publicKey == nil) {
  NSLog(@"SecTrustCopyPublicKey fail");
  return nil;
  }
  
  maxPlainLen = SecKeyGetBlockSize(publicKey) - 12;
  return self;
  }

  - (NSData *) encryptWithData:(NSData *)content {
  
  size_t plainLen = [content length];
  if (plainLen > maxPlainLen) {
  NSLog(@"content(%ld) is too long, must < %ld", plainLen, maxPlainLen);
  return nil;
  }
  
  void *plain = malloc(plainLen);
  [content getBytes:plain
  length:plainLen];
  
  size_t cipherLen = 128; // 当前RSA的密钥长度是128字节
  void *cipher = malloc(cipherLen);
  
  OSStatus returnCode = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, plain,
  plainLen, cipher, &cipherLen);
  
  NSData *result = nil;
  if (returnCode != 0) {
  NSLog(@"SecKeyEncrypt fail. Error Code: %ld", returnCode);
  }
  else {
  result = [NSData dataWithBytes:cipher
  length:cipherLen];
  }
  
  free(plain);
  free(cipher);
  
  return result;
  }

  - (NSData *) encryptWithString:(NSString *)content {
  return [self encryptWithData:[content dataUsingEncoding:NSUTF8StringEncoding]];
  }

  - (void)dealloc{
  CFRelease(certificate);
  CFRelease(trust);
  CFRelease(policy);
  CFRelease(publicKey);
  }

  @end

  使用方法:
  RSA *rsa = [[RSA alloc] init];
  if (rsa != nil) {
  NSLog(@"%@",[rsa encryptWithString:@"test"]);
  }
  else {
  NSLog(@"init rsa error");
  }
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
邪灯是什么意思? 趣头条怎么解绑微信 趣头条APP解绑微信教程 趣头条怎么解绑微信号 趣头条怎样解除微信绑定 魔兽世界7.0古龙之陨怎么做 咸阳男子欲带孩子轻生被救回,成年人的生活有多不易? 陕西咸阳,一男子欲带孩子轻生被救回,轻生带孩子是什么操作? 我是帅哥,为什么还没有人追? 为什么我这么漂亮就是没有一个男人来追我 气死了? 人不在本地,怎么实名制 如何实现用javascript实现rsa加解密 android rsa加解密私钥和公钥怎么用 高分求java的RSA 和IDEA 加密解密算法 非常完整的rsa加密解密软件 有多完整 ios开发rsa加密怎么生成秘钥 rsa的加密算法可以使用什么软件实现密码加密 求RSA加密软件! 中远国际期货新手开户需要什么资料吗 做期货的朋友们,知道这几个公司是正规的吗。 可靠吗 期货平台是正规的吗? 中国在哪些产品上还有比较优势? 怎么设置苹果手机的id 现在的期货交易平台哪个是正规的?怎么判断? 国内的期货公司正规吗? 苹果手机怎么改id? 国内比较大比较好的期货公司有哪些 期货外盘是什么怎么玩的中远国际期货是真的吗 中远国际期货外汇真的有投资者盈利了吗 中远国际期货恒指真的能赚钱吗 中远国际期货做外盘期货受监管吗 怎么判断 如何在浏览器端实现RSA公私钥对生成,加解密 rsa加密rsa加密rsa加密? rsa加密法 详细解释 如何使用16进制编码的RSA公钥进行RSA加密 android 提交的rsa加密,服务端怎么解密 [求助}如何对excel进行RSA加密 银联支付接口使用rsa 数据加密。明文密钥都是16进制的字符串,加密结果和对方给的小工具加密的结果不一样 RSA加密解密问题 RSA加密算法,求大神帮解答 江苏成人高考有哪些优势,你知道吗? word文件的表格复制到&#127380;文件不显示是怎么回事 江苏成考录取分数线2021 word里面表格一页放不下,第二页不显示 江苏成人高考热门问题有哪些?成考小编告诉你! word里面粘贴表格怎么显示不出来 听说今后江苏成考越来越难? 江苏成人高考的入学考试难吗?要考多少分呀 梅艳芳是因为什么原因去世的? 江苏省成人高考 word复制表格到另一个word怎么保持格式?