我有一个RSA密钥(对)表示为大整数模数和指数,需要加密/解密。
我想出了如何使用swift在iOS中根据需要处理键。
我的问题:有没有办法将模数/指数表示转换为标准的SecKeyRef?
两者都被格式化为大int(来自android), 例如,模数看起来像这样:
23986589886077318012326064844037831693417390067186403792990846282531380456965701688980194375481519508455379138899060072530724598302129656976140458275478340281694599774176865257462922861492999970413042311221914141827738166785420817621605554859384423695247859963064446809695729281306530681131568503935369097838468173777374667631401317163094053418212485192857751897040859007584244053136110895205839896478287122804119514727484734998762296502939823974188856604771622873660784676915716476754048257418841069214486772931445697194023455179601077893872576165858771367831752886749210944303260745331014786145738511592470796648651
答案 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_hex2bn
和BN_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。