我正在開發iOS 5的sdk工作,並且我正在通過套接字接口與設備進行通信。該設備需要被髮送大小的2048iOS 5.0:生成的x509大小爲2048的rsa公鑰是270字節而不是294字節。爲什麼?
我生成用下面的代碼密鑰對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個字節(包括開銷)。
這聽起來像我所需要的,但我不知道如何包含這些信息。
有人嗎?
非常天真的觀察:基數64是64個可能性,即每個字節6位。所以一個294字節長的公鑰只有294 * 6 = 1764位的信息。你不需要至少342個字節來編碼基地64位的2048位數量嗎? – Tommy
@Tommy這個問題與base64編碼無關,儘管我非常感謝你的迴應。 –
是的,我完全誤讀了句子「上面的代碼產生公鑰長度爲270字節的NSData;我base64編碼這些數據並將其發送到設備,但它被拒絕。」在'產生270字節的NSData'步驟之前,在精神上放置base64步驟。 270個字節顯然適合2048位密鑰加上週圍的信息。 – Tommy