java rsa证书_java rsa证书 ios 支持吗

展开全部

了之前三个终端进行AES加解密的经验,实现RSA加解密倒不是太复杂。62616964757a686964616fe78988e69d8331333363366135两个关键点:1)RSA需要密钥文件,且密钥文件的格式很重要;2)padding方式需要一致,比较被广泛支持且被很多RAS实现设置为默认padding方式的是PKCS1PADDING V1.5,建议采用。

我是在linux下用openssl生成公钥、私钥文件的,分三个步骤,命令如下:

1、生成公钥public_key.der 和 私钥private_key.pem(加密)

openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem

按照提示,填入私钥的密码,签名证书的组织名、邮件等信息之后,就会生成包含有公钥的证书文件public_key.der和私钥文件private_key.pem。public_key.der文件用于分发到ios客户端进行公钥加密。

2、生成公钥public_key.pem。

openssl rsa -in private_key.pem -pubout -out public_key.pem ,这步生成的public_key.pem用于分发到c++客户端和安卓客户端进行公钥加密。

3、将私钥 private_key.pem(加密)转换为PKCS#8编码格式(且不加密)。

openssl pkcs8 -topk8 -in private_key.pem -out pkcs8_private_key.pem -nocrypt

这步生成的pkcs8_private_key.pem用于在Java服务端进行私钥解密。

RSA的一般用法是在客户端用公钥加密,在网络上传输密文,然后服务端用私钥解密获取原文。所以RSA实现都会支持公钥加密、私钥解密。反过来用私钥加密然后公钥解密,理论上也是可行的。不过我没有试过。如果决定要这么做,祝君好运。

注意:RSA提供的API不像AES,不会自动分块处理。需要手动将原文切割为128-11的块去进行加密 (128是因为采用RSA1024,128=1024/8, 11是因为padding采用版本1.5的PKCS1PADDING。这种分块方式是多个RSA实现的默认方式,推荐使用),每次加密输出的密文长度均是128字节(RSA1024),把这些密文顺序拼装起来。在解密的时候,则是将密文按128字节进行切割,解密后再拼装在一起即可。

======================C++客户端公钥加密=======================

使用大名鼎鼎openssl类库实现,感慨下其API设计得真烂。。。。

注意:虽然输入和输出都是std::string,但不要理解成字符串,实际上都是二进制数据。另外公钥得保存在文件中,我还没找到使用内存中公钥的方法,但对我已经够用了。

std::string EvpHelper::rsaEncryptUsingPublicKeyFile(const std::string& source, const std::string& keyFile)

{

std::string result;

BIO* bp = NULL;

EVP_PKEY* key = NULL;

RSA* rsa = NULL;

EVP_PKEY_CTX* ctx = NULL;

unsigned char* encryptedData = NULL;

try

{

// load public key

OpenSSL_add_all_algorithms();

bp = BIO_new(BIO_s_file());

if (bp == NULL)

{

throw std::runtime_error("BIO_new failed.");

}

if (BIO_read_filename(bp, keyFile.c_str()) <= 0)

{

throw std::runtime_error("BIO_read_filename failed.");

}

rsa = PEM_read_bio_RSA_PUBKEY(bp, NULL, NULL, NULL);

if (rsa == NULL)

{

throw std::runtime_error("PEM_read_bio_RSA_PUBKEY failed.");

}

key = EVP_PKEY_new();

if (key == NULL)

{

throw std::runtime_error("EVP_PKEY_new failed.");

}

EVP_PKEY_assign_RSA(key, rsa);

rsa = NULL;

// encrypt

OpenSSL_add_all_ciphers();

ctx = EVP_PKEY_CTX_new(key, NULL);

if (ctx == NULL)

{

throw std::runtime_error("EVP_PKEY_CTX_new failed.");

}

if (EVP_PKEY_encrypt_init(ctx) <= 0)

{

throw std::runtime_error("EVP_PKEY_encrypt_init failed.");

}

if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)

{

throw std::runtime_error("EVP_PKEY_CTX_set_rsa_padding failed.");

}

encryptedData = new unsigned char[source.size() * 2];

size_t encryptedDataLen = 0;

size_t BLOCK_SIZE = 128 - 11;

size_t sourceDataLen = (int)source.size();

for (size_t i = 0; i < sourceDataLen; i += BLOCK_SIZE)

{

size_t leftBytes = sourceDataLen - i;

size_t sourceBlockLen = (leftBytes <= BLOCK_SIZE) ? leftBytes : BLOCK_SIZE;

size_t encryptedBlockLen = 128;

if(EVP_PKEY_encrypt(ctx, (encryptedData + encryptedDataLen), &encryptedBlockLen,

(const unsigned char *)(source.data() + i), sourceBlockLen) <= 0)

{

throw std::runtime_error("EVP_PKEY_encrypt failed.");

}

encryptedDataLen += encryptedBlockLen;

}

result = std::string((char*)encryptedData, encryptedDataLen);

}

catch (const std::exception& e)

{

LErr(e.what());

}

if (bp != NULL)

{

LInfoCMD(BIO_free(bp));

}

if(rsa != NULL)

{

LInfoCMD(RSA_free(rsa));

}

if (ctx != NULL)

{

LInfoCMD(EVP_PKEY_CTX_free(ctx));

}

if (key != NULL)

{

LInfoCMD(EVP_PKEY_free(key));

}

if (encryptedData != NULL)

{

delete[] encryptedData;

}

return result;

}

======================Java客户端公钥加密=======================

import java.io.BufferedReader;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.InputStreamReader;

import java.security.KeyFactory;

import java.security.interfaces.RSAPublicKey;

import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;

public class RSAEncrypt {

public static RSAPublicKey loadPublicKeyFromFile(String keyPath)

throws Exception {

BufferedReader br = null;

StringBuilder sb = new StringBuilder();

try {

br = new BufferedReader(new InputStreamReader(new FileInputStream(

keyPath)));

String line = null;

while ((line = br.readLine()) != null) {

if (line.charAt(0) == '-') {

continue;

} else {

sb.append(line);

sb.append('\r');

}

}

} finally {

if (br != null) {

br.close();

}

}

return loadPublicKey(sb.toString());

}

public static RSAPublicKey loadPublicKey(String publicKeyStr)

throws Exception {

Base64 decoder = new Base64();

byte[] buffer = decoder.decode(publicKeyStr);

KeyFactory keyFactory = KeyFactory.getInstance("RSA");

X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);

return (RSAPublicKey) keyFactory.generatePublic(keySpec);

}

public static void main(String[] args) throws Exception {

RSAPublicKey publicKey = loadPublicKeyFromFile("public_key.pem");

Cipher cipher = Cipher.getInstance("RSA");

cipher.init(Cipher.ENCRYPT_MODE, publicKey);

byte[] rawText = CommonUtil.readFileContents("from.txt");

FileOutputStream out = null;

try {

out = new FileOutputStream("java_out.bin");

int BLOCK_SIZE = 128 - 11;

for (int i = 0; i < rawText.length; i += BLOCK_SIZE) {

int leftBytes = rawText.length - i;

int length = (leftBytes <= BLOCK_SIZE) ? leftBytes : BLOCK_SIZE;

out.write(cipher.doFinal(rawText, i, length));

}

} finally {

if (out != null) {

out.close();

}

}

}

}

======================IOS客户端公钥加密=======================

static SecKeyRef _public_key = nil;

- (SecKeyRef) getPublicKey{

if (_public_key == nil){

NSString* filePath = [[NSBundle mainBundle] pathForResource:@"public_key" ofType:@"der"];

NSData* certificateData = [NSData dataWithContentsOfFile:filePath];

SecCertificateRef myCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certificateData);

if (myCertificate == nil) {

LErr(@"无法读取公钥内容");

return nil;

}

SecPolicyRef myPolicy = SecPolicyCreateBasicX509();

SecTrustRef myTrust;

OSStatus status = SecTrustCreateWithCertificates(myCertificate,myPolicy,&myTrust);

SecTrustResultType trustResult;

if (status == noErr) {

status = SecTrustEvaluate(myTrust, &trustResult);

}else{

return nil;

}

_public_key = SecTrustCopyPublicKey(myTrust);

CFRelease(myCertificate);

CFRelease(myPolicy);

CFRelease(myTrust);

}

return _public_key;

}

- (NSData*) rsaEncrypt:(NSData*) data{

SecKeyRef key = [self getPublicKey];

if (key == nil) {

return nil;

}

size_t cipherBufferSize = SecKeyGetBlockSize(key);

uint8_t* cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));

size_t blockSize = cipherBufferSize - 11;

size_t blockCount = (size_t)ceil([data length] / (double)blockSize);

NSMutableData *encryptedData = [[NSMutableData alloc] init];

for (int i=0; i

int bufferSize = (int)MIN(blockSize,[data length] - i * blockSize);

NSData *buffer = [data 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{

if (cipherBuffer) free(cipherBuffer);

return nil;

}

}

本回答由提问者推荐

2Q==

已赞过

已踩过<

你对这个回答的评价是?

评论

收起

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值