如何使用 pem 文件加密解密 进行加密和解密

修改MSDN上的示例,使之可以通过RSA证书文件加密和解密,中间遇到一个小问题。
Q:执行ExportParameters()方法时,回报CryptographicException:该项不适于在指定状态下使用(Key not valid for use in specified state)。
A:导入带有私钥的证书时,需要使用"X509KeyStorageFlags"参数标记"私钥可导出"。
X509Certificate2 prvcrt = new X509Certificate2(@"X:\path\to\CA.pfx", "***password***", X509KeyStorageFlags.Exportable);
以下为示例程序:
using System.Collections.G
using System.L
using System.T
namespace TeatApp_Crypto
using System.Security.C
using System.Security.Cryptography.X509C
using System.T
class RSACSPSample
static void Main()
//Create a UnicodeEncoder to convert between byte array and string.
UnicodeEncoding ByteConverter = new UnicodeEncoding();
//Create byte arrays to hold original, encrypted, and decrypted data.
byte[] dataToEncrypt = ByteConverter.GetBytes("Data to Encrypt");
byte[] encryptedD
byte[] decryptedD
X509Certificate2 pubcrt = new X509Certificate2(@"X:\path\to\CA.crt");
RSACryptoServiceProvider pubkey = (RSACryptoServiceProvider)pubcrt.PublicKey.K
X509Certificate2 prvcrt = new X509Certificate2(@"X:\path\to\CA.pfx", "***password***", X509KeyStorageFlags.Exportable);
RSACryptoServiceProvider prvkey = (RSACryptoServiceProvider)prvcrt.PrivateK
//Create a new instance of RSACryptoServiceProvider to generate
//public and private key data.
//using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
//Console.WriteLine(RSA.ToXmlString(false));
//Pass the data to ENCRYPT, the public key information
//(using RSACryptoServiceProvider.ExportParameters(false),
//and a boolean flag specifying no OAEP padding.
encryptedData = RSAEncrypt(dataToEncrypt, pubkey.ExportParameters(false), false);
Console.WriteLine("Encrypted plaintext: {0}", Convert.ToBase64String(encryptedData));
//Pass the data to DECRYPT, the private key information
//(using RSACryptoServiceProvider.ExportParameters(true),
//and a boolean flag specifying no OAEP padding.
decryptedData = RSADecrypt(encryptedData, prvkey.ExportParameters(true), false);
//Display the decrypted plaintext to the console.
Console.WriteLine("Decrypted plaintext: {0}", ByteConverter.GetString(decryptedData));
prvkey.Clear();
pubkey.Clear();
Console.Read();
catch (ArgumentNullException)
//Catch this exception in case the encryption did
//not succeed.
Console.WriteLine("Encryption failed.");
static public byte[] RSAEncrypt(byte[] DataToEncrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
byte[] encryptedD
//Create a new instance of RSACryptoServiceProvider.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
//Import the RSA Key information. This only needs
//toinclude the public key information.
RSA.ImportParameters(RSAKeyInfo);
//Encrypt the passed byte array and specify OAEP padding.
//OAEP padding is only available on Microsoft Windows XP or
encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
return encryptedD
//Catch and display a CryptographicException
//to the console.
catch (CryptographicException e)
Console.WriteLine(e.Message);
return null;
static public byte[] RSADecrypt(byte[] DataToDecrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
byte[] decryptedD
//Create a new instance of RSACryptoServiceProvider.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
//Import the RSA Key information. This needs
//to include the private key information.
RSA.ImportParameters(RSAKeyInfo);
//Decrypt the passed byte array and specify OAEP padding.
//OAEP padding is only available on Microsoft Windows XP or
decryptedData = RSA.Decrypt(DataToDecrypt, DoOAEPPadding);
return decryptedD
//Catch and display a CryptographicException
//to the console.
catch (CryptographicException e)
Console.WriteLine(e.ToString());
return null;
阅读(...) 评论()开源openssl之加密与解密---使用OpenSSL生成非对称密钥
原文地址:
&使用OpenSSL生成非对称密钥
非对称加密算法也叫&公开密钥算法&,不同于对称加密算法,非对称加密算法加密密钥与解密密钥不是一把密钥、非对称密钥对中公钥是可以公开的。
这种算法如果使用公钥进行加密,则只能使用相应的私钥解密;如使用私钥加密,也只能使用相应的公钥解密。而要想通过公钥推导出私钥几乎是不可能的(这样的算法可以使用一些不可逆函数实现)!
OpenSSL支持RSA、DSA、DH三种不同的非对称加密算法。下面我们将介绍如何使用OpenSSL生成并学习使用RSA密钥对。
RSA非对称加密:
一、生成RSA密钥对(opensll genrsa):
1.语法说明:
usage: genrsa [args] [numbits]
& encrypt the generated key with DES in cbc
mode(使用des加密算法加密RSA密钥对)
&-des3 & &
& & & encrypt
the generated key with DES in ede cbc mode (168 bit key)
(使用des3加密算法加密RSA密钥对)
&-aes128, -aes192, -aes256
&encrypt PEM output with cbc aes
(使用aes加密算法加密RSA密钥对)
&-out file &
& & output the key to
'file(输出密钥对文件)
&-passout arg &
&output file pass phrase source (输出密钥文件的口令)
& use F4 (0x10001) for the E value
(使用F4作为公钥的E参数,默认为该选项)
& &use 3 for the E value
(使用3作为公钥的E参数)
&-engine e &
& & use engine e, possibly a
hardware device. (使用第三方设备生成密钥对)
&-rand file:file:... &
&(手动指定随机数文件)
& & &load the
file (or the files in the directory) into
& & &the random
number generator
(1)openssl genrsa -out rsakey.pem 2048 &
&生成一个2048位的密钥对,注:没有对密钥进行加密操作。
(2)openssl genrsa -aes128 -out rsakey.pem -passout pass:111111
&生成一份2048位的密钥对,并对密钥对使用aes算法加密,密钥口令为111111
说明:openssl生成的公钥与私钥默认被存放在一个文件中,当需要提取公钥或私钥时需要使用rsa命令,她可以用来管理密钥文件。
二、管理密钥文件
1.语法说明:
rsa [options] &infile &outfile
where options are
&-inform arg &
& input format - one of DER NET PEM
(输入的密钥编码格式,可以是DER、NET、PEM中的一个,默认为PEM)
&-outform arg &
&output format - one of DER NET PEM
(输出的密钥编码格式)
&-in arg & &
& & input file (输入的密钥文件名称)
&-sgckey & &
& & Use IIS SGC key format
(使用SGC格式,一般很少用到)
&-passin arg &
& input file pass phrase source
(输入密钥文件时提供的密钥文件口令)
&-out arg & &
& &output file (输出的密钥文件名)
&-passout arg &
&output file pass phrase source (输出密钥文件时的口令)
&encrypt PEM output with cbc des
(使用des算法对密钥进行加密)
&-des3 & &
& & & encrypt
PEM output with ede cbc des using 168 bit key (使用des3算法对密钥进行加密)
&-aes128, -aes192, -aes256
& & &encrypt PEM
output with cbc aes &(使用aes算法对密钥进行加密)
&-text & &
& & & print the
key in text (明文输出密钥参数)
&-noout & &
& & &don't print
key out (不输出密钥到文件)
&-modulus & &
& &print the RSA key modulus
(输出RSA密钥模值)
&-check & &
& & &verify key
consistency
&-pubin & &
& & &expect a
public key in input file (默认输入的是密钥对的私钥,使用pubin输入的是密钥的公钥)
&-pubout & &
& & output a public key
(输出公钥到文件)
&-engine e &
& & use engine e, possibly a
hardware device. (使用第三方设备)
& &openssl rsa -in
&filename& -out
&filename& -pubout -des3
&输入一个密钥文件,提起其中的公钥文件,并使用des3算法加密公钥文件。
(注:filename为密钥文件名,实际使用时使用自己的文件名替换,而且实际应用中不会对公钥进行加密,这里仅为演示案例)&
三、使用密钥
1.语法说明:
Usage: rsautl [options]
-in file & &
& &input file
&(输入准备要进行加密或解密的文件)
-out file & &
& output file &(输出加密或解密后的文件)
-inkey file & & input key
&(输入密钥文件)
-keyform arg & &private key
format - default PEM (指定密钥文件格式)
-pubin & & &
& &input is an RSA public
(说明输入的是公钥)
-certin & & &
& input is a certificate carrying an RSA public
key (指明输入的是一个证书)
-ssl & & &
& & &use SSL v2
padding &(数据补齐方式,默认是pkcs)
-raw & & &
& & &use no
padding & (数据补齐方式,默认是pkcs)
-pkcs & & &
& & use PKCS#1 v1.5 padding
(default) (数据补齐方式,默认是pkcs)
-oaep & & &
& & use PKCS#1 OAEP
& (数据补齐方式,默认是pkcs)
-sign & & &
& & sign with private key
&(进行数字签名,即使有私钥加密)
-verify & & &
& verify with public key
&(进行数字签名验证,即使有公钥解密)
-encrypt & &
& &encrypt with public key
(进行解密操作)
-decrypt & &
& &decrypt with private key
&(进行解密操作)
-hexdump & &
& &hex dump output
&(输出十六进制格式)
-engine e & &
& use engine e, possibly a hardware device.
-passin arg & &pass phrase
source &(口令参数)
注:使用RSA进行加密操作时,要求被加密的数据长度与RSA密钥长度一致,但数据大小是不定的,所以当文件数据小于RSA密钥长度时会采用数据补齐,当被加密的文件大于密钥长度时,会被先切割为等长大小的数据块,进行加密操作。
& & 1.openssl rsautl -in
install.log -out bak.log inkey rsakey.pem -pubin -encrypt
使用我们上面案例中生成的rsakey.pem密钥对&install.log&这个文件进行加密,因为使用了pubin选项,所以使用的是公钥加密。
& & 2.openssl rsautl -in
bak.log -out install.log -inkey rsakey.pem -decrypt
使用rsakey.pem密钥中的私钥对&bak.log&文件进行解密。
注:实际应用中很少会使用非对称加密算法对大的文件进行加密操作,而是使用对称加密算法加密文件,然后再使用&非对称加密算法&对&对称算法的密钥&进行加密。
备注:对于大文件(一般大于64字节)就不能采用非对称性加密了
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。C#RSA算法实现+如何将公钥为XML格式转为PEM格式,给object-C使用 - 简书
C#RSA算法实现+如何将公钥为XML格式转为PEM格式,给object-C使用
.net中,处于安全的考虑,RSACryptoServiceProvider类,解密时只有同时拥有公钥和私钥才可以。原因是公钥是公开的,会被多人持有。这样的数据传输是不安全的。
C#中用RSA算法生成公钥和私钥
公钥密钥生成后,保存在同名文件夹下面,如下图:
公钥密钥生成,所在路径【RSA\RSA\bin\Debug】
using System.IO;
using System.Security.C//必须引用
namespace RSA
class Program
static void Main(string[] args)
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
using (StreamWriter writer = new StreamWriter("PrivateKey.xml"))
//这个文件要保密...
writer.WriteLine(rsa.ToXmlString(true));
using (StreamWriter writer = new StreamWriter("PublicKey.xml"))
writer.WriteLine(rsa.ToXmlString(false));
public static void GKEY()//(计算机)生成密钥 GKEY(generate key),generate the RSA public and private keys
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
string publicKey = rsa.ToXmlString(false); // 公钥
string privateKey = rsa.ToXmlString(true); // 私钥
直接断点调式复制公钥密钥出来用
RSA加密解密类
#region RSA
/// &summary&
/// RSA加密
/// &/summary&
/// &param name="publickey"&&/param&
/// &param name="content"&&/param&
/// &returns&&/returns&
public static string RSAEncrypt(string publickey, string content)
publickey = @"&RSAKeyValue&&Modulus&0wE26IHp4U9OLtPhJ+fT8ej6aWORFP8pd++MjUuhkQQm/zhcImbxQbjxtSAftz+kkDwGDFJpSldQPyigOGcUx7PofTc6VhiFik9E9SsxV9n0iEEtqUndDfmBJfPAWt+4UDMwKakgZqFoapDuwjKlTErFvKCyKCs+qN9OZvZwKWk=&/Modulus&&Exponent&AQAB&/Exponent&&/RSAKeyValue&";
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(publickey);
cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);
return Convert.ToBase64String(cipherbytes);
/// &summary&
/// RSA解密
/// &/summary&
/// &param name="privatekey"&&/param&
/// &param name="content"&&/param&
/// &returns&&/returns&
public static string RSADecrypt(string privatekey, string content)
privatekey = @"&RSAKeyValue&&Modulus&0wE26IHp4U9OLtPhJ+fT8ej6aWORFP8pd++MjUuhkQQm/zhcImbxQbjxtSAftz+kkDwGDFJpSldQPyigOGcUx7PofTc6VhiFik9E9SsxV9n0iEEtqUndDfmBJfPAWt+4UDMwKakgZqFoapDuwjKlTErFvKCyKCs+qN9OZvZwKWk=&/Modulus&&Exponent&AQAB&/Exponent&&P&8Ei6NIsZtgV3DQjuGHfGLS6o1O+IUXxzjqLxdMm77yhEPUxR9YPIxODJ2VVTddXSAHxViJJt30yJ7JhVz6cpQw==&/P&&Q&4M49NrmalgVQFMsea2RMB1qN8fAPfIw5G9q9hzsLcWSCmkeRRIQlvPYflVEKAYKiDVVzENETbnnduFXWBABx4w==&/Q&&DP&t+JQbemN0Zi5FQaif6MZzHYKynpNTl75aE0Wj5Pa+RlNr8N6bXNe8Bw/HM2Jw4HQ5oJASvYUk3DVlHS4JuP8VQ==&/DP&&DQ&lT62iv9brp9mU/epgVh71SH8PJPIZEJfo6tryjyb0zMMNcqvmZI1z6aCv0mm3+vPFBUXqCF1yhFj7n4l8FAvSw==&/DQ&&InverseQ&flrvgxHvf4l+fdymEVDgKjsfGqshOpppoNgZj9kpeWBto3o8z++Ki6eSLQT3nVnpx2QCZeTWkxTED4nhSLKscw==&/InverseQ&&D&cQTCg1Eqk7sltmFYxUYgOP/AOPjSufteG9acYwYymPkvZh6rAuY+rSRBmvGE62NUYskzuB/gM6iG2/2HrA5SixfNgCvZ+nsK+kX5pzQRsYdD71ViQW0hOanXwj45I2zHRgBiuTtCUP0fs5pISmQkaeJkDL5pO2l+wvlgl+wunj0=&/D&&/RSAKeyValue&";
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(privatekey);
cipherbytes = rsa.Decrypt(Convert.FromBase64String(content), false);
return Encoding.UTF8.GetString(cipherbytes);
#endregion
如何将公钥为XML格式转为PEM格式?
需要依赖一个第三方库,叫
在线获取安装包的代码如下:
PM & Install-Package BouncyCastle
如果不知道怎么打开vs2013 控制台的请看下面
tips:打开VS2013控制台方法
打开VS2013控制台方法.png
安装第三方库成功图示.png
方法一:在线转换
如何将密钥XML格式和PEM格式互转?【tips:这里说的是密钥,公钥使用其他方法】
一、将XML格式密钥转PEM
public static void XMLConvertToPEM()//XML格式密钥转PEM
var rsa2 = new RSACryptoServiceProvider();
using (var sr = new StreamReader("e:\\PrivateKey.xml"))
rsa2.FromXmlString(sr.ReadToEnd());
var p = rsa2.ExportParameters(true);
var key = new RsaPrivateCrtKeyParameters(
new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent), new BigInteger(1, p.D),
new BigInteger(1, p.P), new BigInteger(1, p.Q), new BigInteger(1, p.DP), new BigInteger(1, p.DQ),
new BigInteger(1, p.InverseQ));
using (var sw = new StreamWriter("e:\\PrivateKey.pem"))
var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(sw);
pemWriter.WriteObject(key);
一、将PEM格式密钥转XML
public static void PEMConvertToXML()//PEM格式密钥转XML
AsymmetricCipherKeyPair keyP
using (var sr = new StreamReader("e:\\PrivateKey.pem"))
var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(sr);
keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
var key = (RsaPrivateCrtKeyParameters)keyPair.P
var p = new RSAParameters
Modulus = key.Modulus.ToByteArrayUnsigned(),
Exponent = key.PublicExponent.ToByteArrayUnsigned(),
D = key.Exponent.ToByteArrayUnsigned(),
P = key.P.ToByteArrayUnsigned(),
Q = key.Q.ToByteArrayUnsigned(),
DP = key.DP.ToByteArrayUnsigned(),
DQ = key.DQ.ToByteArrayUnsigned(),
InverseQ = key.QInv.ToByteArrayUnsigned(),
var rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(p);
using (var sw = new StreamWriter("e:\\PrivateKey.xml"))
sw.Write(rsa.ToXmlString(true));
其他【tips:待测试】
CER和pfx证书.png
生成公钥.png
----------------------------------------------分割线-----------------------------------
下面的代码为object-C(来源于网络)
文件1:rsa.m(object-c)
@author: ideawu
@link: https://github.com/ideawu/Objective-C-RSA
#import "RSA.h"
#import &Security/Security.h&
@implementation RSA
static NSString *base64_encode(NSString *str){
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
if(!data){
return base64_encode_data(data);
static NSString *base64_encode_data(NSData *data){
data = [data base64EncodedDataWithOptions:0];
NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
static NSData *base64_decode(NSString *str){
NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
+ (NSData *)stripPublicKeyHeader:(NSData *)d_key{
// Skip ASN.1 public key header
if (d_key == nil) return(nil);
unsigned long len = [d_key length];
if (!len) return(nil);
unsigned char *c_key = (unsigned char *)[d_key bytes];
unsigned int
if (c_key[idx++] != 0x30) return(nil);
if (c_key[idx] & 0x80) idx += c_key[idx] - 0x80 + 1;
else idx++;
// PKCS #1 rsaEncryption szOID_RSA_RSA
static unsigned char seqiod[] =
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
0x01, 0x05, 0x00 };
if (memcmp(&c_key[idx], seqiod, 15)) return(nil);
idx += 15;
if (c_key[idx++] != 0x03) return(nil);
if (c_key[idx] & 0x80) idx += c_key[idx] - 0x80 + 1;
else idx++;
if (c_key[idx++] != '\0') return(nil);
// Now make a new NSData from this buffer
return([NSData dataWithBytes:&c_key[idx] length:len - idx]);
//credit: http://hg.mozilla.org/services/fx-home/file/tip/Sources/NetworkAndStorage/CryptoUtils.m#l1036
+ (NSData *)stripPrivateKeyHeader:(NSData *)d_key{
// Skip ASN.1 private key header
if (d_key == nil) return(nil);
unsigned long len = [d_key length];
if (!len) return(nil);
unsigned char *c_key = (unsigned char *)[d_key bytes];
unsigned int
= 22; //magic byte at offset 22
if (0x04 != c_key[idx++])
//calculate length of the key
unsigned int c_len = c_key[idx++];
int det = c_len & 0x80;
if (!det) {
c_len = c_len & 0x7f;
int byteCount = c_len & 0x7f;
if (byteCount + idx & len) {
//rsa length field longer than buffer
unsigned int accum = 0;
unsigned char *ptr = &c_key[idx];
idx += byteC
while (byteCount) {
accum = (accum && 8) + *
byteCount--;
// Now make a new NSData from this buffer
return [d_key subdataWithRange:NSMakeRange(idx, c_len)];
+ (SecKeyRef)addPublicKey:(NSString *)key{
NSRange spos = [key rangeOfString:@"-----BEGIN PUBLIC KEY-----"];
NSRange epos = [key rangeOfString:@"-----END PUBLIC KEY-----"];
if(spos.location != NSNotFound && epos.location != NSNotFound){
NSUInteger s = spos.location + spos.
NSUInteger e = epos.
NSRange range = NSMakeRange(s, e-s);
key = [key substringWithRange:range];
key = [key stringByReplacingOccurrencesOfString:@"\r" withString:@""];
key = [key stringByReplacingOccurrencesOfString:@"\n" withString:@""];
key = [key stringByReplacingOccurrencesOfString:@"\t" withString:@""];
key = [key stringByReplacingOccurrencesOfString:@" "
withString:@""];
// This will be base64 encoded, decode it.
NSData *data = base64_decode(key);
data = [RSA stripPublicKeyHeader:data];
if(!data){
//a tag to read/write keychain storage
NSString *tag = @"RSAUtil_PubKey";
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 =
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)publicKey, &persistKey);
if (persistKey != nil){
CFRelease(persistKey);
if ((status != noErr) && (status != errSecDuplicateItem)) {
[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 =
status = SecItemCopyMatching((__bridge CFDictionaryRef)publicKey, (CFTypeRef *)&keyRef);
if(status != noErr){
return keyR
+ (SecKeyRef)addPrivateKey:(NSString *)key{
spos = [key rangeOfString:@"-----BEGIN RSA PRIVATE KEY-----"];
if(spos.length & 0){
epos = [key rangeOfString:@"-----END RSA PRIVATE KEY-----"];
spos = [key rangeOfString:@"-----BEGIN PRIVATE KEY-----"];
epos = [key rangeOfString:@"-----END PRIVATE KEY-----"];
if(spos.location != NSNotFound && epos.location != NSNotFound){
NSUInteger s = spos.location + spos.
NSUInteger e = epos.
NSRange range = NSMakeRange(s, e-s);
key = [key substringWithRange:range];
key = [key stringByReplacingOccurrencesOfString:@"\r" withString:@""];
key = [key stringByReplacingOccurrencesOfString:@"\n" withString:@""];
key = [key stringByReplacingOccurrencesOfString:@"\t" withString:@""];
key = [key stringByReplacingOccurrencesOfString:@" "
withString:@""];
// This will be base64 encoded, decode it.
NSData *data = base64_decode(key);
data = [RSA stripPrivateKeyHeader:data];
if(!data){
//a tag to read/write keychain storage
NSString *tag = @"RSAUtil_PrivKey";
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 =
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)privateKey, &persistKey);
if (persistKey != nil){
CFRelease(persistKey);
if ((status != noErr) && (status != errSecDuplicateItem)) {
[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 =
status = SecItemCopyMatching((__bridge CFDictionaryRef)privateKey, (CFTypeRef *)&keyRef);
if(status != noErr){
return keyR
/* START: Encryption & Decryption with RSA private key */
+ (NSData *)encryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef{
const uint8_t *srcbuf = (const uint8_t *)[data bytes];
size_t srclen = (size_t)data.
size_t block_size = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t);
void *outbuf = malloc(block_size);
size_t src_block_size = block_size - 11;
NSMutableData *ret = [[NSMutableData alloc] init];
for(int idx=0; idx& idx+=src_block_size){
//NSLog(@"%d/%d block_size: %d", idx, (int)srclen, (int)block_size);
size_t data_len = srclen -
if(data_len & src_block_size){
data_len = src_block_
size_t outlen = block_
OSStatus status = noE
status = SecKeyEncrypt(keyRef,
kSecPaddingPKCS1,
srcbuf + idx,
if (status != 0) {
NSLog(@"SecKeyEncrypt fail. Error Code: %d", status);
[ret appendBytes:outbuf length:outlen];
free(outbuf);
CFRelease(keyRef);
+ (NSString *)encryptString:(NSString *)str privateKey:(NSString *)privKey{
NSData *data = [RSA encryptData:[str dataUsingEncoding:NSUTF8StringEncoding] privateKey:privKey];
NSString *ret = base64_encode_data(data);
+ (NSData *)encryptData:(NSData *)data privateKey:(NSString *)privKey{
if(!data || !privKey){
SecKeyRef keyRef = [RSA addPrivateKey:privKey];
if(!keyRef){
return [RSA encryptData:data withKeyRef:keyRef];
+ (NSData *)decryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef{
const uint8_t *srcbuf = (const uint8_t *)[data bytes];
size_t srclen = (size_t)data.
size_t block_size = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t);
UInt8 *outbuf = malloc(block_size);
size_t src_block_size = block_
NSMutableData *ret = [[NSMutableData alloc] init];
for(int idx=0; idx& idx+=src_block_size){
//NSLog(@"%d/%d block_size: %d", idx, (int)srclen, (int)block_size);
size_t data_len = srclen -
if(data_len & src_block_size){
data_len = src_block_
size_t outlen = block_
OSStatus status = noE
status = SecKeyDecrypt(keyRef,
kSecPaddingNone,
srcbuf + idx,
if (status != 0) {
NSLog(@"SecKeyEncrypt fail. Error Code: %d", status);
//the actual decrypted data is in the middle, locate it!
int idxFirstZero = -1;
int idxNextZero = (int)
for ( int i = 0; i & i++ ) {
if ( outbuf[i] == 0 ) {
if ( idxFirstZero & 0 ) {
idxFirstZero =
idxNextZero =
[ret appendBytes:&outbuf[idxFirstZero+1] length:idxNextZero-idxFirstZero-1];
free(outbuf);
CFRelease(keyRef);
+ (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey{
NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
data = [RSA decryptData:data privateKey:privKey];
NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+ (NSData *)decryptData:(NSData *)data privateKey:(NSString *)privKey{
if(!data || !privKey){
SecKeyRef keyRef = [RSA addPrivateKey:privKey];
if(!keyRef){
return [RSA decryptData:data withKeyRef:keyRef];
/* END: Encryption & Decryption with RSA private key */
/* START: Encryption & Decryption with RSA public key */
+ (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey{
NSData *data = [RSA encryptData:[str dataUsingEncoding:NSUTF8StringEncoding] publicKey:pubKey];
NSString *ret = base64_encode_data(data);
+ (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubKey{
if(!data || !pubKey){
SecKeyRef keyRef = [RSA addPublicKey:pubKey];
if(!keyRef){
return [RSA encryptData:data withKeyRef:keyRef];
+ (NSString *)decryptString:(NSString *)str publicKey:(NSString *)pubKey{
NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
data = [RSA decryptData:data publicKey:pubKey];
NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+ (NSData *)decryptData:(NSData *)data publicKey:(NSString *)pubKey{
if(!data || !pubKey){
SecKeyRef keyRef = [RSA addPublicKey:pubKey];
if(!keyRef){
return [RSA decryptData:data withKeyRef:keyRef];
/* END: Encryption & Decryption with RSA public key */
文件2:rsa.h(object-c)
@author: ideawu
@link: https://github.com/ideawu/Objective-C-RSA
#import &Foundation/Foundation.h&
@interface RSA : NSObject
// return base64 encoded string
+ (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubK
// return raw data
+ (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubK
// return base64 encoded string
// enc with private key NOT working YET!
//+ (NSString *)encryptString:(NSString *)str privateKey:(NSString *)privK
// return raw data
//+ (NSData *)encryptData:(NSData *)data privateKey:(NSString *)privK
// decrypt base64 encoded string, convert result to string(not base64 encoded)
+ (NSString *)decryptString:(NSString *)str publicKey:(NSString *)pubK
+ (NSData *)decryptData:(NSData *)data publicKey:(NSString *)pubK
+ (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privK
+ (NSData *)decryptData:(NSData *)data privateKey:(NSString *)privK
If you keep working hard,you can exprience a better world!
原版:http://blog.csdn.net/jun2ran/article/details/6491375 第一章 前言第二章 证书第三章 加密算法第四章 协议第五章 入门第六章 指令 verify第七章 指令asn1parse第八章 指令CA(一)第九章 指令CA(二...
公钥密码系统及RSA公钥算法 本文简单介绍了公开密钥密码系统的思想和特点,并具体介绍了RSA算法的理论基础,工作原理和具体实现过程,并通过一个简单例子说明了该算法是如何实现。在本文的最后,概括说明了RSA算法目前存在的一些缺点和解决方法。 关键词:公钥密码体制 , 公钥 ,...
2018-Read-Record 记录我的2018学习历程 文中首先解释了加密解密的一些基础知识和概念,然后通过一个加密通信过程的例子说明了加密算法的作用,以及数字证书的出现所起的作用。接着对数字证书做一个详细的解释,并讨论一下windows中数字证书的管理,最后演示使用m...
嘟哝嘟哝:最近接到一个任务:在客户端动态生成RSA密钥对,然后向服务器发送这个密钥对中的公钥字符串,由服务器进行公钥加密,返回加密后的信息,再由客户端使用私钥进行解密。我在网上查阅了大量的资料,但是大多是利用公钥私钥文件,或者直接接收RSA公私钥字符串进行加密解密,没有生成...
1 基础 1.1 对称算法 描述:对称加密是指加密过程和解密过程使用相同的密码。主要分:分组加密、序列加密。 原理:XOR运算,将二进制数据进行XOR运算,两次同样的操作得到原文,所以大致过程就是加密-&A xor B = C,解密-&C xor B = A(B就是密钥)。...
【关于危机感】 整理金融科技史的过程中,看到技术的变革逐步替代淘汰人力,连决策都有可能被机器取代,顿生危机感。该成为什么样的人、从事什么样的工作、选择怎样的积累和追求,未来才不会被AI替代? 老板课上也提出这个问题,那些金融精英们几乎达成一致意见:那些无形的intellig...
14种异常纹的具体情况 1三星高照是指离位 2 3线尾端出现米子纹容易造成心脑血管病。 2 肝分线 必须1线2线之间长度在无名指中线之前,肝脏损伤,小时候肝炎或伤寒造成的等 3 3线护线 3线外护线一般的是5线,3线的断如果外护线能连接,此人免役力没有多大损伤,3线内护线一...
壹 | 一直在等待的呆小孩 呆小孩手里有一颗糖,不剥开吃,也不给别人,就这么一直拿在手上。 有一天,他被一群坏小孩堵在了小胡同。 为首的坏小孩只想抢了他的糖,他认为这个小男孩的糖一定比别的糖都甜。 呆小孩宁愿挨揍也不把糖交出去,最后糖碎成了糖末。 坏小孩舔了一口,发现这个糖...
本文转自:李笑来《七年就是一辈子》 原文链接: http://zhibimo.com/read/xiaolai/reborn-every-7-years/A24.html 自学从来都是少数人的特长。 我们所谓的“自主升级自己的操作系统”,就是反复自学的过程。人为什么一定要有...
喜欢一个作家真的是有原因的,之前看过东野圭吾那几部比较出名的经典之作,最近又连看了几部他的小说,算算也有十几部了。再来继续聊聊想法。 东野圭吾作为一名职业小说家,真的已经很成功。其作品畅销也是有原因的。虽说万变不离爱情、亲情、友情等元素,所有作品也不外乎着重于发掘人性的美丑...

我要回帖

更多关于 电脑加密文件怎么解密 的文章

 

随机推荐