我使用以下代码在iOS上生成密钥
let parameters: [String: AnyObject] = [kSecAttrKeyType as String: kSecAttrKeyTypeRSA, kSecAttrKeySizeInBits as String: 1024]
var publicKeyPtr, privateKeyPtr: SecKey?
let result = SecKeyGeneratePair(parameters, &publicKeyPtr, &privateKeyPtr)
print(result)
let publicKey = publicKeyPtr!
let privateKey = privateKeyPtr!
let encodedPublicKey = convertSecKeyToBase64(publicKey)!
func convertSecKeyToBase64(inputKey: SecKey) ->String? {
// First Temp add to keychain
let tempTag = "de.a-bundle-id.temp"
let addParameters :[String:AnyObject] = [
String(kSecClass): kSecClassKey,
String(kSecAttrApplicationTag): tempTag,
String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
String(kSecValueRef): inputKey,
String(kSecReturnData):kCFBooleanTrue
]
var keyPtr: AnyObject?
let result = SecItemAdd(addParameters, &keyPtr)
switch result {
case noErr:
let data = keyPtr! as! NSData
// Remove from Keychain again:
SecItemDelete(addParameters)
let encodingParameter = NSDataBase64EncodingOptions(rawValue: 0)
return data.base64EncodedStringWithOptions(encodingParameter)
default:
print("Error: \(result)")
return nil
}
}
编码的公钥如下所示
MIGJAoGBAJZhrrBPuKvq8RuVPeg02D2iPahmVS9oomaqxITNcifBO6hhYomp4mlbubSWMYiHPbpeX7+gmG41B7E5BSJ7nHq7KZ9OMqiAekY5JhRmJlAhmKsBmjrSNbt0wqNXl3dxjj/sc1qauQBXY8X5fhEmatWDwvfb7nq/8yloPc5iAUalAgMBAAE=
在Android上解密时,我收到错误消息 java.security.spec.InvalidKeySpecException:java.lang.RuntimeException:error:0D0680A8:asn1编码例程:ASN1_CHECK_TLEN:标记错误
显然,在iOS上生成的密钥类型不是Android代码所需的类型,我如何让iOS使用X509类型?以下是Android代码
public static String encrypt(String text, Context c, String pub) {
try {
byte[] pubKey = Base64.decode(pub, 0);
KeyFactory factory = KeyFactory.getInstance("RSA");
EncodedKeySpec keySpec = new X509EncodedKeySpec(pubKey);
PublicKey key = factory.generatePublic(keySpec);
Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] bytes = text.getBytes("UTF-8");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for (int i = 0; i < (bytes.length / 128 + 1); i++) {
int start = i * 128;
int blockLength;
if (i == bytes.length / 128)
blockLength = bytes.length - i * 128;
else
blockLength = 128;
if (blockLength > 0) {
byte[] encrypted = cipher
.doFinal(bytes, start, blockLength);
baos.write(encrypted);
}
}
byte[] encrypted = baos.toByteArray();
return Base64.encodeToString(encrypted, 0);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
答案 0 :(得分:0)
我引用Berin在blog
中写的内容首先,当您从iPhone钥匙串导出密钥时,它会以缩减格式导出 - 只需公钥和指数,而不需要在完全编码的公钥中使用任何其他ASN.1内容。 java加密函数通常需要一个完全编码的密钥(OID和all)。
总之,SecKeyGeneratePair
生成的公钥不是完整格式。为了使Android能够使用它,需要手动扩展。可以在该博客中找到更多内容。
答案 1 :(得分:0)
将CryptoExportImportManager.swift文件从下面拖放到您的项目中。这将使您能够以PEM和DER格式导出在iOS上生成的密钥,这些密钥可以传递给Android和其他平台。自述文件中的信息将详细说明。