Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何从文件中恢复RSA?_Ios_Key_Rsa_Public - Fatal编程技术网

Ios 如何从文件中恢复RSA?

Ios 如何从文件中恢复RSA?,ios,key,rsa,public,Ios,Key,Rsa,Public,我想从文件中恢复公钥。以下是有效的Java代码: PublicKey readPubKeyFromFile(AssetFileDescriptor cle) throws IOException { // read RSA public key byte[] encodedKey = new byte[(int) cle.getDeclaredLength()]; cle.createInputStream().read(encodedKey); // crea

我想从文件中恢复公钥。以下是有效的Java代码:

PublicKey readPubKeyFromFile(AssetFileDescriptor cle) throws IOException {
    // read RSA public key
    byte[] encodedKey = new byte[(int) cle.getDeclaredLength()];
    cle.createInputStream().read(encodedKey);

    // create public key
    X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey);
    PublicKey pk = null;
    try {
        KeyFactory kf = KeyFactory.getInstance("RSA");
        pk = kf.generatePublic(publicKeySpec);
    } catch(Exception e) {
        Logger.getInstance().logError("KeyUtils", e.toString());
    }
    return pk;
}
以下是不起作用的iOS代码:

-(SecKeyRef)readPublicKeyFromFile:(NSString*)filename andExtension:(NSString*)extension {

NSString*   filePath = [[NSBundle mainBundle] pathForResource:filename ofType:extension];
NSData*     encodedKey = [NSData dataWithContentsOfFile:filePath];

CFDataRef myCertData = (CFDataRef)encodedKey;

SecCertificateRef cert = SecCertificateCreateWithData (kCFAllocatorSystemDefault, myCertData);
CFArrayRef certs = CFArrayCreate(kCFAllocatorDefault, (const void **) &cert, 1, NULL);
SecPolicyRef policy = SecPolicyCreateBasicX509();

SecTrustRef trust;

OSStatus check =  SecTrustCreateWithCertificates(certs, policy, &trust);

if (check != noErr)
{
    NSLog(@"Problem extracting public key from file: %@", filename);
    return nil;
}

SecTrustResultType trustResult;
SecTrustEvaluate(trust, &trustResult);
SecKeyRef pub_key_leaf = SecTrustCopyPublicKey(trust);

return pub_key_leaf;
}

知道我的iOS代码有什么问题吗?

我已经测试了你的代码,没有问题。问题似乎与您试图获取公钥的证书的格式有关

函数SecCertificateCreateWithData()假定您提供的证书为DER格式。您发现的大多数证书都是用base64编码的,就像著名的.pem格式一样。我已经使用格式正确的DER证书(证书格式developer.apple.com通过openssl转换为DER)测试了您的代码,并且正确提取了公钥

要将.pem证书转换为DER,只需在终端中使用openssl即可:

openssl x509 -in developer.apple.com.pem  -outform der -out cert.der
之后,输出证书文件应该可以正常工作,代码不会出现问题

但是您可以在应用程序本身上转换证书,您只需要获取de x509 base64编码的证书(假设您使用的是.pem编码的证书)并将其转换为二进制

下面是一个示例,说明了如何做到这一点:

此代码将假定证书采用以下标准编码:

-----BEGIN CERTIFICATE-----
< your base64 encoded certificate goes here >
-----END CERTIFICATE-----
然后,在功能完善的代码中进行一个小小的修改,就可以实现以下目的:

-(SecKeyRef)readPublicKeyFromCertificate:(NSData *)binaryCertificate {

    NSData *encodedKey = binaryCertificate;

    CFDataRef myCertData = (CFDataRef)CFBridgingRetain(encodedKey);

    SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorSystemDefault, myCertData);
    SecPolicyRef policy = SecPolicyCreateBasicX509();

    SecTrustRef trust;
    //If you only have one certificate you don't need to put it inside an array
    OSStatus check =  SecTrustCreateWithCertificates(cert, policy, &trust);

    if (check != noErr)
    {
        NSLog(@"Problem extracting public key from certificate");
        return nil;
    }

    SecTrustResultType trustResult;
    SecTrustEvaluate(trust, &trustResult);
    SecKeyRef pub_key_leaf = SecTrustCopyPublicKey(trust);

    return pub_key_leaf;
}
那就叫它:

NSData *data = [self getBinaryCertificateFromPemEncodedFile:@"developer" andExtension:@"pem"];
SecKeyRef key = [self readPublicKeyFromCertificate:data];
NSLog(@"%@", key);
如果您的证书“有效”,您应该看到:

2014-09-15 21:52:13.275 cert[15813:60b] <SecKeyRef algorithm id: 1,
key type: RSAPublicKey, version: 2, block size: 2048 bits, exponent: {hex: 10001, decimal: 65537},
modulus: BE19E30F47F2D31F27D576CF007B3E615F986D14AFD0D52B825E01E90BA3E1CBB6F3A472E6AECDC28BC13D0B6E58FC497ACF61D80F274E4799602DA4F819E54ADDE2FBFA89FC4EB2172501DDED8DE0FBDDBC5550CC018C73E1FD8152C905DE850862B8D57596025DE1908D8337E95637AF0F52C4A11DA178FF737DCE09471BC0A49DAD7DB39F1BA1B693D3A12F9CA50EF388B50292C73076BF1EEE412A5CFA940E99D4CF07F17FAC87F0D0E2FC8FA3ACDDEEFCCE8AFEC407B94536FCB1E4ACF34773728D189F85EAE4347E0BF868D25C7CE89F8A29B4E6865C68F4F915DFA540549EE9333007145D367FE2852622AAD776F3E5D505A02E5155CC8646A01C1031,
addr: 0x9a48200>
2014-09-1521:52:13.275证书[15813:60b]

为了进行测试,我使用了developer.apple.com的证书,您可以检查日志中的公钥并进行比较。

欢迎使用stackoverflow。它是如何工作的?返回nil:SecCertificateRef cert=SecCertificateCreateWithData(kCFAllocatorSystemDefault,myCertData);任何评论,我都站在同一个位置上。您好,实际上我必须使用openssl并自己解析文件。看起来这些键是用Java生成的,格式不是标准的:s
2014-09-15 21:52:13.275 cert[15813:60b] <SecKeyRef algorithm id: 1,
key type: RSAPublicKey, version: 2, block size: 2048 bits, exponent: {hex: 10001, decimal: 65537},
modulus: BE19E30F47F2D31F27D576CF007B3E615F986D14AFD0D52B825E01E90BA3E1CBB6F3A472E6AECDC28BC13D0B6E58FC497ACF61D80F274E4799602DA4F819E54ADDE2FBFA89FC4EB2172501DDED8DE0FBDDBC5550CC018C73E1FD8152C905DE850862B8D57596025DE1908D8337E95637AF0F52C4A11DA178FF737DCE09471BC0A49DAD7DB39F1BA1B693D3A12F9CA50EF388B50292C73076BF1EEE412A5CFA940E99D4CF07F17FAC87F0D0E2FC8FA3ACDDEEFCCE8AFEC407B94536FCB1E4ACF34773728D189F85EAE4347E0BF868D25C7CE89F8A29B4E6865C68F4F915DFA540549EE9333007145D367FE2852622AAD776F3E5D505A02E5155CC8646A01C1031,
addr: 0x9a48200>