通过ios实现RSA加密和解密

在加密和解密中,我们需要了解的知识有什么事openssl;RSA加密算法的基本原理;如何通过openssl生成最后我们需要的der和p12文件。

废话不多说,直接写步骤:

第一步:openssl来生成公钥和私钥证书,最后需要得到公钥证书和私钥证书

这是在mac OX系统下显示的证书,如果我们用文本编辑器打开它,会发现里面是----BEGIN RSA 开头  并且----END RSA 结尾的一串字符串。

第二步:我们需要在代码中写我们的加密和机密方法,加密的字符串通过公钥进行加密,加密后的字符串也可以通过私钥进行解密。

1.在命令行下通过openssl指令获得证书

//生成长度为 1024 的私钥:private_key.pem (文件名可自定义)
openssl genrsa -out private_key.pem 1024

//使用私钥文件创建所需的证书:rsaCertReq.csr(文件名可自定义)
openssl req -new -key private_key.pem -out rsaCertReq.csr

//使用 x509 创建证书:rsaCert.crt(文件名可自定义)
openssl x509 -req -days 3650 -in rsaCertReq.csr -signkey private_key.pem -out rsaCert.crt

//生成 .der 格式的公钥:public_key.der(文件名可自定义)
openssl x509 -outform der -in rsaCert.crt -out public_key.der

//生成解密所需 .p12文件:private_key.p12(文件名可自定义)
openssl pkcs12 -export -out private_key.p12 -inkey private_key.pem -in rsaCert.crt

在命令行种可能需要你的一些信息去生成公钥和私钥

Country Name (2 letter code) [AU]:CN                                              // 国家码

State or Province Name (full name) [Some-State]:china                     //地区码

Locality Name (eg, city) []:wuhan                   // 本地码

Organization Name (eg, company) [Internet Widgits Pty Ltd]:airway   // 公司名称

Organizational Unit Name (eg, section) []:airway                               // 部门

Common Name (eg, YOUR name) []:airway                                       // 名字

Email Address []:                            //邮箱

注意:在生成密钥对的时候需要填入 私钥的提取密码,请记住,解密的时候需要用到。

2.我们需要完善我们的代码来实现RSA加密和解密

通过在命令行中的操作,我们最后可以得到我们需要的公钥和私钥文件。

static SecKeyRef _public_key = nil;
        // 从公钥证书文件中获取到公钥的SecKeyRef指针:  @"public_key" ofType:@"der"
        NSString *publicKeyPath = [paramsDict stringValueForKey:@"publicKey" defaultValue:@""];
        publicKeyPath = [self getPathWithUZSchemeURL:publicKeyPath];
        if (![[NSFileManager defaultManager] fileExistsAtPath:publicKeyPath]) {
            [self sendResultEventWithCallbackId:rsaCbId dataDict:@{@"status":[NSNumber numberWithBool:false]} errDict:@{@"code":@(-1)} doDelete:NO];
            return;
        }
        NSData *certificateData = [[NSData alloc]initWithContentsOfFile:publicKeyPath];
        SecCertificateRef myCertificate =  SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certificateData);
        SecPolicyRef myPolicy = SecPolicyCreateBasicX509();
        SecTrustRef myTrust;
        OSStatus status = SecTrustCreateWithCertificates(myCertificate,myPolicy,&myTrust);
        SecTrustResultType trustResult;
        if (status == noErr) {
            status = SecTrustEvaluate(myTrust, &trustResult);
        }
        _public_key = SecTrustCopyPublicKey(myTrust);
        CFRelease(myCertificate);
        CFRelease(myPolicy);
        CFRelease(myTrust);

        SecKeyRef key = _public_key;
        size_t cipherBufferSize = SecKeyGetBlockSize(key);
        uint8_t *cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));
        NSData *stringBytes = [inString dataUsingEncoding:NSUTF8StringEncoding];
        size_t blockSize = cipherBufferSize - 11;
        size_t blockCount = (size_t)ceil([stringBytes length] / (double)blockSize);
        NSMutableData *encryptedData = [[NSMutableData alloc] init];
        NSString *outString = [[NSString alloc] init];
        for (int i=0; i<blockCount; i++) {
            int bufferSize = MIN(blockSize,[stringBytes length] - i * blockSize);
            NSData *buffer = [stringBytes subdataWithRange:NSMakeRange(i * blockSize, bufferSize)];
            OSStatus status = SecKeyEncrypt(key, kSecPaddingPKCS1, (const uint8_t *)[buffer bytes],
                                            [buffer length], cipherBuffer, &cipherBufferSize);
            if (status == noErr){
                NSData *encryptedBytes = [[NSData alloc] initWithBytes:(const void *)cipherBuffer length:cipherBufferSize];
                [encryptedData appendData:encryptedBytes];
            } else{
                outString = @"";
            }
        }
        if (cipherBuffer) {
            free(cipherBuffer);
        }
        outString = [encryptedData base64Encoding];
}
return outString;
NSString *password = [paramsDict stringValueForKey:@"password" defaultValue:@""];
    NSString *inString = [paramsDict stringValueForKey:@"data" defaultValue:@""];
    NSString *value = @"";
    if (inString.length <= 0) {
        //err:1
        return value;
    } else {
        // 从私钥证书文件中获取到公钥的SecKeyRef指针:  @"private_key" ofType:@"pem"
        NSString *privateKeyPath = [paramsDict stringValueForKey:@"privateKey" defaultValue:@""];
        privateKeyPath = [self getPathWithUZSchemeURL:privateKeyPath];
        if (![[NSFileManager defaultManager] fileExistsAtPath:privateKeyPath]) {
            return value;
        }
        NSData *p12Data = [[NSData alloc]initWithContentsOfFile:privateKeyPath];
        SecKeyRef privateKeyRef = NULL;
        NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
        [options setObject:password forKey:(__bridge id)kSecImportExportPassphrase];
        CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
        OSStatus securityError = SecPKCS12Import((__bridge CFDataRef) p12Data, (__bridge CFDictionaryRef)options, &items);
        if (securityError == noErr && CFArrayGetCount(items) > 0) {
            CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
            SecIdentityRef identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
            securityError = SecIdentityCopyPrivateKey(identityApp, &privateKeyRef);
            if (securityError != noErr) {
                privateKeyRef = NULL;
            }
        } else {
            return value;
        }
        CFRelease(items);

        NSData *cipherData = [NSData dataWithBase64EncodedString:inString];
        //        NSData* decryptData = [self rsaDecryptData: data];
        size_t cipherLen = [cipherData length];
        void *cipher = malloc(cipherLen);
        [cipherData getBytes:cipher length:cipherLen];
        size_t plainLen = SecKeyGetBlockSize(privateKeyRef) - 12;
        void *plain = malloc(plainLen);
        OSStatus status = SecKeyDecrypt(privateKeyRef, kSecPaddingPKCS1, cipher, cipherLen, plain, &plainLen);
        if (status != noErr) {
            return value;
        }
        NSData *decryptedData = [[NSData alloc] initWithBytes:(const void *)plain length:plainLen];
        value = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
        NSMutableString *outString = [[NSMutableString alloc] init];
        //如果没有进行加密直接解密,outString 将为 nil
        if (!value && decryptedData && decryptedData.length > 0) {
            Byte *datas = (Byte*)[decryptedData bytes];
            outString = [NSMutableString stringWithCapacity:decryptedData.length * 2];
            for(int i = 0; i < decryptedData.length; i++){
                [outString appendFormat:@"%02x", datas[i]];
            }
            value = [outString copy];
        }
        return value;
    }
时间: 2024-08-09 02:01:53

通过ios实现RSA加密和解密的相关文章

iOS rsa加密与解密

转自 --响铃  IOS rsa加密与解密 ras加密需要两组秘钥,一组公共秘钥,一组私有秘钥. 生成命令: openssl req -x509 -out public_key.der -outform der -new -newkey rsa:2048 -keyout private_key.pem public_key.der为公共秘钥文件,private_key.pem为私有秘钥文件. 生成ios可引用的私有秘钥文件.pfx: 1. OpenSSL rsa -in private_key.

C#实现RSA加密和解密详解

原文:C#实现RSA加密和解密详解 RSA加密解密源码: Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography;

RSA加密和解密工具类

1 import org.apache.commons.codec.binary.Base64; 2 3 import javax.crypto.Cipher; 4 import java.security.*; 5 import java.security.spec.PKCS8EncodedKeySpec; 6 import java.security.spec.X509EncodedKeySpec; 7 import java.util.HashMap; 8 import java.util

Android和IOS关于RSA加密以及服务端解密的研究实现

一.  密钥对的生成 RSA加密解密,类似于支付宝中的加解密功能,以前的app使用的是DES加密即对称加密算法,只需要一个密钥:而采用RSA实现加解密需要一个密钥对,即公钥和私钥.所以首先要做的操作是生成一个密钥对,在window 7环境下,这里借用支付宝demo中的openssl命令行工具,毕竟是通用的,密钥对的生成流程大致如下: 1.生成RSA私钥 <span style="white-space:pre"> </span>genrsa -out rsa_p

RSA加密、解密、签名、验签 DSA签名、验签

重要的事情说三遍,该篇文章主要是验证JAVA的RSA签名.验签的测试代码,主要代码参考 http://xw-z1985.iteye.com/blog/1837376 重要的事情说三遍,该篇文章主要是验证JAVA的RSA签名.验签的测试代码,主要代码参考 http://xw-z1985.iteye.com/blog/1837376 重要的事情说三遍,该篇文章主要是验证JAVA的RSA签名.验签的测试代码,主要代码参考 http://xw-z1985.iteye.com/blog/1837376 下

php 的rsa加密与解密

系统:centos6.5 linux系统生成公私钥对方法: openssl genrsa -out rsa_private_key.pem 1024 openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 第一条命令生成

C# 与 Java Rsa加密与解密互通

Rsa 加密标准的制定已经过去了十多年了. 这两天在看rsa 加密的文章,基本上都是在说 .net 与 java 之间的 rsa加密是不能互通的.因为项目有用到,所以花了点时间对rsa加密做了一点点了解,发现,不管是java 还是 C# 都对 rsa 的标准加密进行了实现, 是 对于标准是实现,不能互通就讲不过去了. 今天特意写了一段java 代码试了一下,发现是完全可以的. 密钥的描述: C#(.net) 中有三种方式导出密钥,一种是blob,一种是 xml 另一种是参数,其中xml 的方式是

利用openssl生成公钥、私钥 Rsa加密、解密及验证签名

//获取公钥私钥 X509Certificate2 c4 = DataCertificate.GetCertFromCerFile(path + "\\cer\\xx.pem"); string PublicKey = c4.PublicKey.Key.ToXmlString(false);//公钥 X509Certificate2 c3 = DataCertificate.GetCertificateFromPfxFile(path + "\\cer\\yy.pfx&quo

rsa加密后端解密出现中文乱码解决方法

今天被这个中文乱码的问题困扰了一天,故事是这样的: 前端rsa加密,后端去解密,但是呢有中文的时候解密出来就乱了,想了各种办法未果: 结论,既然中文乱码,我就不传中文就行了哈.在加密之前用 // 前端加密前将所有中文encoder掉 var en = encodeURIComponent(str); // 后台再转换回来就行了 String result = java.net.URLDecoder.decode(en ,"UTF-8"); 这个方法很巧妙的利用了解决url加密的工具,何