-2

如何在 Web 服务端解密我的 iOS CryptoKit 加密值?

类似于这个 SO 问题: Java 中的 CryptoKit

或者这个 SO question

我可以创建自己的 SymmetricKey,我们都知道字符串吗?如何在 Java PhP 或 .NET 中解密我的值?(我了解所有这些语言并且可以翻译,该应用程序目前在 php 中)

Apple 在他们的操场上的代码:

let key = SymmetricKey(size: .bits256)     //<--- how to share with web service???
let themeSongPath = Bundle.main.path(forResource: "ThemeSong", ofType: "aif")!
let themeSong = FileManager.default.contents(atPath: themeSongPath)!


// below code is from Apple Playground
let encryptedContentAES = try! AES.GCM.seal(themeSong, using: key).combined
/*:
 The client decrypts using the same key, assumed to have been obtained out-of-band.
 */
let sealedBoxAES = try! AES.GCM.SealedBox(combined: encryptedContentAES!)

//HOW DO I DO THIS ON WEB SERVICE SIDE??? either in java or php or .net
let decryptedThemeSongAES = try! AES.GCM.open(sealedBoxAES, using: key)

assert(decryptedThemeSongAES == themeSong)
/*:
 You use a sealed box to hold the three outputs of the encryption operation: a nonce, the ciphertext, and a tag.
 */
// The nonce should be unique per encryption operation.
// Some protocols require specific values to be used, such as monotonically increasing counters.
// If none is passed during the during the encryption, CryptoKit randomly generates a safe value for you.

let nonceAES = sealedBoxAES.nonce

// The ciphertext is the encrypted plaintext, and is the same size as the original data.
let ciphertextAES = sealedBoxAES.ciphertext

// The tag provides authentication.
let tagAES = sealedBoxAES.tag

// The combined property holds the collected nonce, ciphertext and tag.
assert(sealedBoxAES.combined == nonceAES + ciphertextAES + tagAES)

链接到游乐场

4

2 回答 2

1

所以我想我真正的问题是如何使用 cryptokit 加密并使用 php (web app.

这两个链接帮助了我:

Swift CryptoKit 和浏览器

Java中的iOS CryptoKit

SWIFT代码:

func encryptAES_GCMCryptoKit()->String {
    let newkeyString1 = "I9GiP/cK4YKko8CeNF5F8X6/E6jt0QnV" //has to be 32 bytes for a 256 bit encryption or you will get the error key wrong size
    let newKey = SymmetricKey(data: newkeyString1.data(using: .utf8)!)
    let mySealedBox = try AES.GCM.seal(userString, using: newKey, nonce: iv)
    let iv = AES.GCM.Nonce()

do{
        let mySealedBox = try AES.GCM.seal(userString, using: newKey, nonce: iv)
        let dataToShare = mySealedBox.combined?.base64EncodedData()      
    
      // The combined property holds the collected nonce, ciphertext and tag.
        assert(mySealedBox.combined == nonceAES + ciphertextAES + tagAES)
}catch {
        print("error \(error)")
       
    }
}

php代码:

function decryptStringAES_GCM($combinedInput='')  //64 base encoded combine string
{
    $key = "I9GiP/cK4YKko8CeNF5F8X6/E6jt0QnV"; // <- 256 bit key - same key is on the swift side
    
    $combined = base64_decode($combinedInput);  //<- $combinedInput will be different every time even for the same value
    $tag = substr($combined, -16);
    $nonce = substr($combined, 0, 12);
    $length = strlen($combined)-16-12;      //take out tag and nonce (iv) lengths
    $cipherText = substr($combined, 12, $length);
    
    $res_non = openssl_decrypt($cipherText, 'aes-256-gcm', $key, OPENSSL_RAW_DATA| OPENSSL_NO_PADDING, $nonce, $tag); 
    
    return $res_non //decrypted string

您也可以像第一个链接那样在单独的调用中将密钥传递回服务器。

于 2021-06-25T15:48:14.160 回答
0

观看 WWDC 视频后:WWDC Cryptokit 2019 视频

在大约 29 分 20 秒时,他们建议您最初从服务器获取关键数据。所以你可以通过这样做来创建密钥:

密钥创建代码

这样服务器和应用程序具有相同的密钥。或者,如果您可以控制双方,您可以知道您的服务器密钥是什么,并使用您都知道的字符串中的数据创建密钥。

于 2021-06-23T14:25:31.377 回答