代码之家  ›  专栏  ›  技术社区  ›  My3

将RSA公钥(2048位)从XML格式转换为用于iOS的DER ASN.1公钥

  •  0
  • My3  · 技术社区  · 10 年前

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

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

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

    我也尝试过 Generate Public Key From Modulus & Exponent on iOS using OpenSSL 库,但无法使用此生成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 回复  |  直到 7 年前
        1
  •  1
  •   Community rcollyer    7 年前

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

    方法#1。将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/NlPGLXKN5L47XYQrPcs8/xp2PYYW7hjezx7Ig6+WDJnxSbWgxZQMaiyO1XbCl5yT2AxUj4od/DfylsVe8ljq154rEb+vCjr/LDPxExijHouJYDNqFV1jglWHfftBAzEZ ADPx7NpHsgXSYrFeVY/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”获取更多详细信息。