我正在开发iOS 5的sdk,我正在通过套接字接口与设备进行通信。此设备需要发送一个大小为2048的base64编码的rsa x509公钥。
我使用以下代码生成密钥对:
OSStatus status = noErr;
NSMutableDictionary *privateKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary *publicKeyAttr= [[NSMutableDictionary alloc] init];
NSMutableDictionary *keyPairAttr = [[NSMutableDictionary alloc] init];
NSData * publicTag = [NSData dataWithBytes:publicKeyIdentifier
length:strlen((const char *)publicKeyIdentifier)];
NSData * privateTag = [NSData dataWithBytes:privateKeyIdentifier
length:strlen((const char *)privateKeyIdentifier)];
SecKeyRef publicKey = NULL;
SecKeyRef privateKey = NULL;
[keyPairAttr setObject:(__bridge id)kSecAttrKeyTypeRSA
forKey:(__bridge id)kSecAttrKeyType];
[keyPairAttr setObject:[NSNumber numberWithInt:2048]
forKey:(__bridge id)kSecAttrKeySizeInBits];
[privateKeyAttr setObject:[NSNumber numberWithBool:YES]
forKey:(__bridge id)kSecAttrIsPermanent];
[privateKeyAttr setObject:privateTag
forKey:(__bridge id)kSecAttrApplicationTag];
[publicKeyAttr setObject:[NSNumber numberWithBool:YES]
forKey:(__bridge id)kSecAttrIsPermanent];
[publicKeyAttr setObject:publicTag
forKey:(__bridge id)kSecAttrApplicationTag];
[keyPairAttr setObject:privateKeyAttr
forKey:(__bridge id)kSecPrivateKeyAttrs];
[keyPairAttr setObject:publicKeyAttr
forKey:(__bridge id)kSecPublicKeyAttrs];
status = SecKeyGeneratePair((__bridge CFDictionaryRef)keyPairAttr,
&_publicKey, &_privateKey);
然后我使用以下代码获取公钥的原始数据:
NSData* publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)];
OSStatus sanityCheck = noErr;
NSData* publicKeyBits = nil;
NSMutableDictionary* queryPublicKey = [[NSMutableDictionary alloc] init];
[queryPublicKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[queryPublicKey setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag];
[queryPublicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
// Temporarily add key to the Keychain, return as data:
NSMutableDictionary* attributes = [queryPublicKey mutableCopy];
[attributes setObject:(__bridge id)key forKey:(__bridge id)kSecValueRef];
[attributes setObject:@YES forKey:(__bridge id)kSecReturnData];
CFTypeRef result;
sanityCheck = SecItemAdd((__bridge CFDictionaryRef)attributes, &result);
if (sanityCheck == errSecSuccess) {
publicKeyBits = CFBridgingRelease(result);
// Remove from Keychain again:
(void)SecItemDelete((__bridge CFDictionaryRef)queryPublicKey);
}
return publicKeyBits;
以上代码为公钥产生 270字节长的NSData;我base64对这些数据进行编码并将其发送到设备,但它被拒绝了。
我的同事在工作中已完成对android的相同功能的实现,并按如下方式生成密钥对:
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair key = kpg.generateKeyPair();
他使用:
key.getPublic().getEncoded()
访问 294字节长的公钥数据,以及设备接受的数据。
另外,如果我获取他生成的公钥的原始字节,并使用我的base64编码和发送,设备也会接受这个。
这有什么区别?为什么他的关键是294字节,而我的是270?我该如何解决这个问题?任何帮助将不胜感激。
修改
请注意,这不会计算“这是RSA公钥”的编码;这会占用额外的24个字节(包括开销)。
这听起来像我需要的,虽然我不知道如何包含这些信息。
任何?
答案 0 :(得分:4)
以下是答案:http://blog.wingsofhermes.org/?p=42
"首先,当您从iPhone钥匙串导出密钥时,它会以缩减格式导出 - 只需公钥和指数,而不需要任何其他ASN.1内容编码的公钥。"
我认为这是这样的;我整天都在用显示器砸头。
血腥的苹果。