2015-10-20 113 views
1
工作

我使用下面的代碼RSA密鑰對生成的iOS不會在Android

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上產生解密iOS上的鍵,我得到錯誤 java.security.spec.InvalidKeySpecException:java.lang.RuntimeException:錯誤: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

我引述帳戶berin在他blog

First off, when you export a key from the iPhone keychain, it’s exported in a cut down format – just the public key and exponent without any of the other ASN.1 stuff you’d expect in a fully encoded public key. The java crypto functions generally expect a fully encoded key (OID and all).

寫了一句話,由SecKeyGeneratePair生成的公鑰是不是一個完整的格式。爲了使Android能夠使用它,需要手動擴展。更多可以在該博客中找到。