[英]Convert RSA Public key (2048 bit) from XML format to DER ASN.1 public key for iOS
我试图从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上从Modulus&Exponent生成公钥 ,但是无法使用此生成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对象,那就太好了。
提前致谢 :)
我可以通过上述两种方法成功解决此问题。 这是我的解决方案:
方法1:通过此链接将XML密钥转换为使用256字节密钥(2048位)的ASN.1 DER格式。 https://github.com/meinside/iphonelib/blob/master/security/CryptoUtil.m#L67
方法2。可以使用以下代码创建的RSA对象(参考: 使用OpenSSL从iOS上的Modulus&Exponent生成公钥)成功加密:
`的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.
请参阅RSA_public_encrypt`。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.