簡體   English   中英

使用Java Security生成的XCode導入公共密鑰文件

[英]XCode import public key file generated with Java Security

我有一個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();

另一方面,我有xcode,它使用此publickey.der加密數據:

    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之間的區別。

謝謝。

您的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.    
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM