1

私は次のようにJavaジェネレーターの公開鍵を持っています:

final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
final KeyPair key = keyGen.generateKeyPair();
PublicKey pubkey = key.getPublic();
byte[] key = pubkey .getEncoded();
FileOutputStream keyfos = new FileOutputStream("publicKey.der");
keyfos.write(key);
keyfos.close();

また、この publickey.der を使用してデータを暗号化する xcode があります。

    NSString *publicKeyPath = [[NSBundle mainBundle] pathForResource:@"public_key"
ofType:@"der"];
if (publicKeyPath == nil) {
NSLog(@"Can not find public_key.der");
return nil;
}
NSDate *publicKeyFileContent = [NSData dataWithContentsOfFile:publicKeyPath];
if (publicKeyFileContent == nil) {
NSLog(@"Can not read from public_key.der");
return nil;
 }
certificate = SecCertificateCreateWithData(kCFAllocatorDefault, ( __bridge CFDataRef)publicKeyFileContent);
if (certificate == nil) {
NSLog(@"Can not read certificate from public_key.der");
return nil;
}
policy = SecPolicyCreateBasicX509();
OSStatus returnCode = SecTrustCreateWithCertificates(certificate, policy, &trust);
if (returnCode != 0) {
NSLog(@"SecTrustCreateWithCertificates fail. Error Code: %ld", returnCode);
return nil;

    }
SecTrustResultType trustResultType;
returnCode = SecTrustEvaluate(trust, &trustResultType);
if (returnCode != 0) {
 NSLog(@"SecTrustEvaluate fail. Error Code: %ld", returnCode);
return nil;
}
publicKey = SecTrustCopyPublicKey(trust);
if (publicKey == nil) {
 NSLog(@"SecTrustCopyPublicKey fail");
return nil;
}

しかし、public_key.derから証明書を読み取れないと私に言いました。

まあ、openssl public_key を使えばうまくいきます。なんで?openssl keypairgenerator の違いはどれですか。

ありがとう。

4

1 に答える 1

0

Java コードは実際の証明書を作成しません。公開鍵を生成しました。Java で生成された公開鍵から PublicKeyRef を取得する方法については、この投稿で説明しています。ファイルから xcode でこの公開鍵を読み取ることができますが、その後、いくつかの追加作業を行う必要があります。

- (NSData *) extractPublicKeyFromRawFormattedKey: (NSData *) rawFormattedKey {
/* Now strip the uncessary ASN encoding guff at the start */
unsigned char * bytes = (unsigned char *)[rawFormattedKey bytes];
size_t bytesLen = [rawFormattedKey length];

/* Strip the initial stuff */
size_t i = 0;
if (bytes[i++] != 0x30)
    return FALSE;

/* Skip size bytes */
if (bytes[i] > 0x80)
    i += bytes[i] - 0x80 + 1;
else
    i++;

if (i >= bytesLen)
    return FALSE;

if (bytes[i] != 0x30)
    return FALSE;

/* Skip OID */
i += 15;

if (i >= bytesLen - 2)
    return FALSE;

if (bytes[i++] != 0x03)
    return FALSE;

/* Skip length and null */
if (bytes[i] > 0x80)
    i += bytes[i] - 0x80 + 1;
else
    i++;

if (i >= bytesLen)
    return FALSE;

if (bytes[i++] != 0x00)
    return FALSE;

if (i >= bytesLen)
    return FALSE;

/* Here we go! */
NSData * extractedKey = [NSData dataWithBytes:&bytes[i] length:bytesLen - i];

return extractedKey;

}

次に、リンゴの例のメソッドを使用して

- (SecKeyRef)addPeerPublicKey:(NSString *)peerName keyBits:(NSData *)publicKey {
OSStatus sanityCheck = noErr;
SecKeyRef peerKeyRef = NULL;
CFTypeRef persistPeer = NULL;

LOGGING_FACILITY( peerName != nil, @"Peer name parameter is nil." );
LOGGING_FACILITY( publicKey != nil, @"Public key parameter is nil." );

NSData * peerTag = [[NSData alloc] initWithBytes:(const void *)[peerName UTF8String] length:[peerName length]];
NSMutableDictionary * peerPublicKeyAttr = [[NSMutableDictionary alloc] init];

[peerPublicKeyAttr setObject:(id)kSecClassKey forKey:(id)kSecClass];
[peerPublicKeyAttr setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
[peerPublicKeyAttr setObject:peerTag forKey:(id)kSecAttrApplicationTag];
[peerPublicKeyAttr setObject:publicKey forKey:(id)kSecValueData];
[peerPublicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnPersistentRef];

sanityCheck = SecItemAdd((CFDictionaryRef) peerPublicKeyAttr, (CFTypeRef *)&persistPeer);

// The nice thing about persistent references is that you can write their value out to disk and
// then use them later. I don't do that here but it certainly can make sense for other situations
// where you don't want to have to keep building up dictionaries of attributes to get a reference.
// 
// Also take a look at SecKeyWrapper's methods (CFTypeRef)getPersistentKeyRefWithKeyRef:(SecKeyRef)key
// & (SecKeyRef)getKeyRefWithPersistentKeyRef:(CFTypeRef)persistentRef.

LOGGING_FACILITY1( sanityCheck == noErr || sanityCheck == errSecDuplicateItem, @"Problem adding the peer public key to the keychain, OSStatus == %d.", sanityCheck );

if (persistPeer) {
    peerKeyRef = [self getKeyRefWithPersistentKeyRef:persistPeer];
} else {
    [peerPublicKeyAttr removeObjectForKey:(id)kSecValueData];
    [peerPublicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnRef];
    // Let's retry a different way.
    sanityCheck = SecItemCopyMatching((CFDictionaryRef) peerPublicKeyAttr, (CFTypeRef *)&peerKeyRef);
}

LOGGING_FACILITY1( sanityCheck == noErr && peerKeyRef != NULL, @"Problem acquiring reference to the public key, OSStatus == %d.", sanityCheck );

[peerTag release];
[peerPublicKeyAttr release];
if (persistPeer) CFRelease(persistPeer);
return peerKeyRef;

}

公開鍵を生成できます

- (void)generatePublicKeyByFile {
NSString *publicKeyPath = [[NSBundle mainBundle] pathForResource:@"public_key"
ofType:@"der"];
NSData *publicKeyFileContent = [NSData dataWithContentsOfFile:publicKeyPath];
NSData *publicKey = [self extractPublicKeyFromRawFormattedKey:publicKeyFileContent];
[[SecKeyWrapper sharedWrapper] removePeerPublicKey:@"peerName"]; //remove public key if it is already added.
SecKeyRef publicKeyRef = [[SecKeyWrapper sharedWrapper]addPeerPublicKey:@"peerName" keyBits:publicKey]; //our goal.    
}
于 2013-10-01T13:47:58.110 に答える