0

我正在尝试从 C# 以 XML 格式共享的 PublicKey(2048 位)数据创建 SecKeyRef。数据如下所示:

<Modulus>yLgpOFtg14GjDdle0xha2JCbYrpmKCpXcv+zFx2pi6OlIF8cOSXF6dE19W15+WfuCc2SznVQlVDOLp/NlPGLXKN5L47XYQrPpcls8/xp2PYYW7hjezx7Ig6+WDJnUxSbWgxZQMaiyO1XbCKll5yT2AxUj4od/DfylsVe8ljq154rEb+vCjr/LDpxExijHouJYDNqFV1jglWHWfftBQAzEZADPx7NpHsgXSYrFeVY/WH38GIlyO8FvGWIuDiwyRrHUEXhljmBqAJ3lgULyik3ShfjpN1W4h7BbzFs27mpiAPMtPgToADPNzOadRWFJQjeVVknIq5g6SHHnaZK8wBwrQ==</Modulus><Exponent>AQAB</Exponent>]]>"

我遵循了将 XML Dsig 格式转换为 DER ASN.1 公钥链接,该链接仅适用于 1024 位密钥,但相同的逻辑无法对上述密钥(2048 位)进行 DER 编码。虽然我可以在评论中看到需要为 256 字节密钥修改转换逻辑,但我无法成功修改!

我也尝试过使用 OpenSSL 库在 iOS 上从模数和指数生成公钥,但未能生成 RSA 对象!以下是示例:

NSString *mod = @"yLgpOFtg14GjDdle0xha2JCbYrpmKCpXcv+zFx2pi6OlIF8cOSXF6dE19W15+WfuCc2SznVQlVDOLp/NlPGLXKN5L47XYQrPpcls8/xp2PYYW7hjezx7Ig6+WDJnUxSbWgxZQMaiyO1XbCKll5yT2AxUj4od/DfylsVe8ljq154rEb+vCjr/LDpxExijHouJYDNqFV1jglWHWfftBQAzEZADPx7NpHsgXSYrFeVY/WH38GIlyO8FvGWIuDiwyRrHUEXhljmBqAJ3lgULyik3ShfjpN1W4h7BbzFs27mpiAPMtPgToADPNzOadRWFJQjeVVknIq5g6SHHnaZK8wBwrQ==";

BIGNUM *modulus = BN_new();
int res = BN_hex2bn(&modulus,[mod cStringUsingEncoding:NSUTF8StringEncoding]);

BIGNUM *exponent = BN_new();
NSString *exp = @"AQAB";
res = BN_hex2bn(&exponent,[exp cStringUsingEncoding:NSUTF8StringEncoding]);

RSA *rsa = RSA_new();

rsa->n = BN_new();
BN_copy(rsa->n,modulus);
rsa->e = BN_new();
BN_copy(rsa->e,exponent);
rsa->iqmp=NULL;
rsa->d=NULL;
rsa->p=NULL;
rsa->q=NULL;

FILE *fp = fopen("/publicKey.pem", "wb");
int suc = PEM_write_RSAPublicKey(fp, rsa, NULL, NULL, 0, 0, NULL);

生成的 publicKey.pem 文件显然是空的!如果有人可以帮助我将 XML RSA 公钥导入 iOS SecKetRef 对象,那就太好了。

提前致谢 :)

4

1 回答 1

1

我可以通过上述两种方法成功解决这个问题。这是我的解决方案:

方法 # 1.Convert XML 密钥到 ASN.1 DER 格式使用 256 字节密钥(2048 位)与此链接。 https://github.com/meinside/iphonelib/blob/master/security/CryptoUtil.m#L67

方法 #2. 可以使用以下代码创建的 RSA 对象成功加密(参考:Generate Public Key From Modulus & Exponent on iOS using OpenSSL ):

`NSString *mod = @"yLgpOFtg14GjDdle0xha2JCbYrpmKCpXcv+zFx2pi6OlIF8cOSXF6dE19W15+WfuCc2SznVQlVDOLp/NlPGLXKN5L47XYQrPpcls8/xp2PYYW7hjezx7Ig6+WDJnUxSbWgxZQMaiyO1XbCKll5yT2AxUj4od/DfylsVe8ljq154rEb+vCjr/LDpxExijHouJYDNqFV1jglWHWfftBQAzEZADPx7NpHsgXSYrFeVY/WH38GIlyO8FvGWIuDiwyRrHUEXhljmBqAJ3lgULyik3ShfjpN1W4h7BbzFs27mpiAPMtPgToADPNzOadRWFJQjeVVknIq5g6SHHnaZK8wBwrQ==";

NSString *exp = @"AQAB";

NSData *modBits = [[NSData alloc] initWithBase64EncodedString:mod options:NSDataBase64DecodingIgnoreUnknownCharacters];
NSData *expBits = [[NSData alloc] initWithBase64EncodedString:exp options:NSDataBase64DecodingIgnoreUnknownCharacters];

unsigned char *modBin = (unsigned char *)malloc(modBits.length);
[modBits getBytes:modBin length:modBits.length];

unsigned char *expBin = (unsigned char *)malloc(expBits.length);
[expBits getBytes:expBin length:expBits.length];


BIGNUM *returnValue = BN_new();
BIGNUM *modulus = BN_bin2bn(modBin, modBits.length, returnValue);
BIGNUM *exponent = BN_bin2bn(expBin, expBits.length, NULL);

RSA *rsa = RSA_new();
rsa->n = BN_new();
BN_copy(rsa->n,modulus);
rsa->e = BN_new();
BN_copy(rsa->e,exponent);
rsa->iqmp=NULL;
rsa->d=NULL;
rsa->p=NULL;
rsa->q=NULL;


unsigned char *orgTxt = (unsigned char*)strdup("Hello World");

int lenrsa = RSA_size( rsa ) - 11; // man RSA_public_encrypt for the -11

unsigned char *encrText = (unsigned char *)malloc(lenrsa);
int result = RSA_public_encrypt(strlen((const char*)orgTxt), orgTxt, encrText, rsa,RSA_PKCS1_PADDING);

Be sure of the glen param of RSA_public_encrypt API, it depends on the padding used.man RSA_public_encrypt` 了解更多详情。

于 2014-09-04T04:47:13.343 回答