简体   繁体   English

从模数/指数中获取 SecKeyRef

[英]Get SecKeyRef from modulus/exponent

I have a RSA key (pair) represented as big integeger modulus and exponent and need to encrypt/decrypt with those.我有一个 RSA 密钥(对)表示为大整数模数和指数,需要用它们加密/解密。

I figured out how to handle keys as needed in iOS using swift.我想出了如何使用 swift 在 iOS 中根据需要处理键。

To my question: Is there any way to convert the modulus/exponent representation to a standard SecKeyRef?我的问题:有没有办法将模数/指数表示转换为标准的 SecKeyRef?

Both is formatted as big int (coming from android), a modulus for example looks like this:两者都被格式化为 big int(来自 android),例如一个模数看起来像这样:

I had exactly the same task - given a modulus and an exponent I had to create a public key and encrypt a message using that key.我有完全相同的任务 - 给定一个模数和一个指数,我必须创建一个公钥并使用该密钥加密消息。 After a long time spent in reading and trying various libraries, I was able to accomplish this with OpenSSL.在花了很长时间阅读和尝试各种库之后,我能够使用 OpenSSL 完成此任务。 I'm posting my way of doing it below.我在下面发布了我的做法。 Although it's written in Objective-C, it might be helpful.虽然它是用 Objective-C 编写的,但它可能会有所帮助。

NSData* message, modulus, exponent;
BIGNUM* mod = BN_bin2bn((unsigned char *)[modulus bytes], (int)modulus.length, NULL);
if (mod == NULL) {
    NSLog(@"Error creating modulus BIGNUM");
}

BIGNUM* exp = BN_bin2bn((unsigned char *)[exponent bytes], (int)exponent.length, NULL);
if (exp == NULL) {
    NSLog(@"Error creating exponent BIGNUM");
}

RSA* rsa = RSA_new();
rsa->pad = 0;
rsa->e = exp;
rsa->n = mod;

int keylen = RSA_size(rsa);
unsigned char* enc = malloc(keylen);
char* err = malloc(130);
int status = RSA_public_encrypt((int)message.length, (const unsigned char*)[message bytes], enc, rsa, RSA_NO_PADDING);

if (status != -1) {
    NSData* encryptedMessage = [NSData dataWithBytes:enc length:keylen];
    NSLog(@"Encryption SUCCESSFUL: %@", encryptedMessage);
}
else {
    ERR_load_crypto_strings();
    ERR_error_string(ERR_get_error(), err);
    NSLog(@"Encryption failed with error: %s", err);
}

free(enc);
free(err);

So first I'm creating big integers out of my NSData modulus and exponent.所以首先我从我的NSData模数和指数中创建大整数。 You already have them as big integers, but if they're not represented as OpenSSL's BIGNUM type, you'll have to convert them.您已经将它们作为大整数,但如果它们没有表示为 OpenSSL 的BIGNUM类型,则必须转换它们。 BIGNUM has other useful functions for creating big integers like BN_hex2bn and BN_dec2bn - these create big integers out of C strings containing hexadecimal or decimal numbers. BIGNUM有其他有用的函数来创建大整数,如BN_hex2bnBN_dec2bn - 这些函数从包含十六进制或十进制数的 C 字符串中创建大整数。 In my case the modulus and exponent are stored as a byte array in an NSData and BN_bin2bn creates a BIGNUM directly from that.在我的情况下,模数和指数被存储作为在字节数组NSDataBN_bin2bn创建BIGNUM直接从。

Moving on, I create an RSA structure which represents a key and holds the modulus and exponent, and the enc buffer, which will hold the raw encrypted bytes.继续,我创建了一个RSA结构,它表示一个密钥并保存模数和指数,以及enc缓冲区,它将保存原始加密字节。 The length of enc is the same as the size of the key, because RSA can not encrypt messages longer that the key. enc的长度与密钥的大小相同,因为 RSA 无法加密比密钥更长的消息。

The main work is done by the RSA_public_encrypt() function.主要工作由RSA_public_encrypt()函数完成。 It takes five arguments - the size of the message that you're going to encrypt, the actual message bytes, an output buffer to store the encrypted message in, the RSA key and a padding scheme.它需要五个参数——您要加密的消息的大小、实际的消息字节、用于存储加密消息的输出缓冲区、RSA 密钥和填充方案。 I'm using no padding here, because my message is exactly the same size as the key, but in the rsa.h there are macros that represent the most common padding schemes.我在这里没有使用填充,因为我的消息与密钥的大小完全相同,但在rsa.h有代表最常见填充方案的宏。

Lastly I check the status which holds the number of encrypted bytes and print an error message if something went wrong.最后,我检查保存加密字节数的status ,并在出现问题时打印错误消息。

I hope this will help you and somebody else.我希望这会帮助你和其他人。 Tell me if you managed to do it in Swift.告诉我你是否设法在 Swift 中做到了。 Cheers ;-)干杯;-)

PS Adding OpenSSL to your iOS project is easy using CocoaPods. PS 使用 CocoaPods 可以轻松地将 OpenSSL 添加到您的 iOS 项目。 Just add只需添加

pod 'OpenSSL-Universal', '1.0.1.k'

to your podfile.到您的 podfile。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM