我正在寻找 CryptoKit 的设置/参数,这将允许我在 iOS 应用程序和 Java 应用程序之间共享数据。流程如下所示: - 使用 CryptoKit 使用固定密钥和随机初始化向量 (IV) 加密文本。- 在 Java 应用程序中,使用标准 javax 库使用相同的固定密钥执行解密。随机 IV 将与加密文本一起与应用程序一起传输/共享。
同样,也需要反向操作,其中使用 JavaX 库使用固定密钥和随机 IV 对文本进行加密。随机 IV 和加密文本与 iOS 应用程序共享,它应该使用 CryptoKit 对其进行解密。
下面是Java中加密和解密的代码
public static byte[] encrypt(byte[] plaintext, byte[] key, byte[] IV) throws Exception
{
// Get Cipher Instance
Cipher cipher = Cipher.getInstance("AES_256/GCM/NoPadding");
// Create SecretKeySpec
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
// Create GCMParameterSpec
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, IV);
// Initialize Cipher for ENCRYPT_MODE
cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);
// Perform Encryption
byte[] cipherText = cipher.doFinal(plaintext);
return cipherText;
}
public static String decrypt(byte[] cipherText, byte[] key, byte[] IV) throws Exception
{
// Get Cipher Instance
Cipher cipher = Cipher.getInstance("AES_256/GCM/NoPadding");
// Create SecretKeySpec
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
// Create GCMParameterSpec
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, IV);
// Initialize Cipher for DECRYPT_MODE
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
// Perform Decryption
byte[] decryptedText = cipher.doFinal(cipherText);
return new String(decryptedText);
}
CryptoKit 命令如下:
let mykey = SymmetricKey(data: passhash)
let myiv = try AES.GCM.Nonce()
let mySealedBox = try AES.GCM.seal(source.data(using: .utf8)!, using: mykey, nonce: myiv)
let myNewSealedBox = try AES.GCM.SealedBox(nonce: myiv, ciphertext: mySealedBox.ciphertext, tag: mySealedBox.tag)
let myText = try String(decoding: AES.GCM.open(myNewSealedBox, using: mykey), as: UTF8.self)
以下是在 Java 中生成加密文本的步骤:
int GCM_IV_LENGTH = 12;
//Generate Key
MessageDigest md = MessageDigest.getInstance("SHA265");
byte[] key = md.digest("pass".getBytes(StandardCharsets.UTF_8));
// Generate IV
SecureRandom sr = new SecureRandom(pass.getBytes(StandardCharsets.UTF_8));
byte[] IV = new byte[GCM_IV_LENGTH];
sr.nextBytes(IV);
//Encrypt
byte[] cipherText = encrypt("Text to encrypt".getBytes(), key, IV);
//Base64 Encoded CipherText
String cipherTextBase64 = Base64.getEncoder().encodeToString(cipherText);
要在 SWIFT CryptoKit 中对此进行解密,我首先需要使用此 CipherText 创建一个密封盒,但是,用于创建密封盒的 CryptoKit API 需要以下内容:
- Nonce/IV(在上面可用)
- 密文(在上面可用)
- 标签(不知道从哪里得到这个????)
AES.GCM.SealedBox(nonce: , ciphertext: , tag: )
另一种方式,让我们首先在 CryptoKit 中加密数据
let mykey = SymmetricKey(data: SHA256.hash(data: "12345".data(using: .utf8)!))
let myiv = AES.GCM.Nonce()
let mySealedBox = try AES.GCM.seal("Text to encrypt".data(using: .utf8)!, using: mykey, nonce: myiv)
let cipherText = mySealedBox.cipherText.base64EncodedString()
let iv = myiv.withUnsafeBytes{
return Data(Array($0)).base64EncodedString()
}
如果我将此 IV 和 CipherText 连同密钥(“12345”字符串的 SHA265 哈希)一起传递给 Java Decrypt 函数,我会收到一个 TAG 不匹配错误。