从模数/指数中获取SecKeyRef

时间:2015-06-10 14:47:18

标签: ios swift encryption rsa

我有一个RSA密钥(对)表示为大整数模数和指数,需要加密/解密。

我想出了如何使用swift在iOS中根据需要处理键。

我的问题:有没有办法将模数/指数表示转换为标准的SecKeyRef?

两者都被格式化为大int(来自android), 例如,模数看起来像这样:

  

23986589886077318012326064844037831693417390067186403792990846282531380456965701688980194375481519508455379138899060072530724598302129656976140458275478340281694599774176865257462922861492999970413042311221914141827738166785420817621605554859384423695247859963064446809695729281306530681131568503935369097838468173777374667631401317163094053418212485192857751897040859007584244053136110895205839896478287122804119514727484734998762296502939823974188856604771622873660784676915716476754048257418841069214486772931445697194023455179601077893872576165858771367831752886749210944303260745331014786145738511592470796648651

1 个答案:

答案 0 :(得分:2)

我有完全相同的任务 - 给定模数和指数我必须创建公钥并使用该密钥加密消息。经过很长一段时间阅读和尝试各种库,我能够通过OpenSSL实现这一目标。我在下面发布我的做法。虽然它是用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);

首先,我要从NSData模数和指数中创建大整数。您已将它们作为大整数,但如果它们未被表示为OpenSSL的BIGNUM类型,则您必须转换它们。 BIGNUM还有其他有用的函数来创建大整数,如BN_hex2bnBN_dec2bn - 这些函数用包含十六进制或十进制数字的C字符串创建大整数。在我的例子中,模数和指数存储为NSData中的字节数组,BN_bin2bn直接从中创建BIGNUM

继续,我创建一个RSA结构,它代表一个键并保存模数和指数,以及enc缓冲区,它将保存原始加密字节。 enc的长度与密钥的大小相同,因为RSA无法加密比密钥更长的消息。

主要工作由RSA_public_encrypt()功能完成。它需要五个参数 - 您要加密的消息的大小,实际的消息字节,存储加密消息的输出缓冲区,RSA密钥和填充方案。我在这里没有使用填充,因为我的消息与密钥的大小完全相同,但在rsa.h中有代表最常见填充方案的宏。

最后,我检查status,其中包含加密字节数,并在出现问题时打印错误消息。

我希望这会对你和其他人有所帮助。告诉我你是否设法在Swift中做到了。干杯; - )

P.S。使用CocoaPods可以轻松地将OpenSSL添加到iOS项目中。只需添加

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

到您的podfile。