【问题标题】:How to decrypt a file at a time that has been encrypted in chunks (AES GCM)如何一次解密已分块加密的文件(AES GCM)
【发布时间】:2023-02-20 22:44:23
【问题描述】:

对于 AES GCM 加密,我使用标准的 crypto/cipher 包,文件以 5 兆字节的块通过网络到达,每个块都用一个密钥和一个随机数加密。加密块被添加到共享文件中。您需要能够在对 Decrypt() 函数的一次调用中解密文件(而不是以 5 兆字节为单位解密文件)。研究了资料,我得出的结论是,如果你学会了如何为每个块定义伽罗瓦计数器,这是可能的,问题是crypto/cipher包并不意味着伽罗瓦计数器的传输。请推荐另一个包来解决我的问题(Go)或者告诉我是否有可能解决这个问题crypto/cipher但是以不同的方式?

【问题讨论】:

    标签: go crypt aes-gcm


    【解决方案1】:

    您仍然可以通过调用 Open() 函数来解密文件,即使文件是按块加密的。但是您需要为每个块提供正确的随机数和身份验证标记。

    考虑以下功能:

    import (
        "crypto/aes"
        "crypto/cipher"
        "io/ioutil"
    )
    
    func DecryptFile(key []byte, encryptedFilePath string) ([]byte, error) {
        // Read the encrypted file into memory
        encryptedFile, err := ioutil.ReadFile(encryptedFilePath)
        if err != nil {
            return nil, err
        }
    
        // Create a new AES cipher block with the given key
        block, err := aes.NewCipher(key)
        if err != nil {
            return nil, err
        }
    
        // Create a GCM mode cipher using the AES cipher block
        gcm, err := cipher.NewGCM(block)
        if err != nil {
            return nil, err
        }
    
        // Split the encrypted file into chunks of 5 megabytes
        chunkSize := 5 * 1024 * 1024
        numChunks := len(encryptedFile) / chunkSize
        if len(encryptedFile) % chunkSize != 0 {
            numChunks++
        }
    
        // Decrypt each chunk using the same GCM object, providing the correct nonce and authentication tag for each chunk
        var plaintext []byte
        for i := 0; i < numChunks; i++ {
            chunkStart := i * chunkSize
            chunkEnd := (i + 1) * chunkSize
            if chunkEnd > len(encryptedFile) {
                chunkEnd = len(encryptedFile)
            }
    
            nonce := encryptedFile[chunkStart : chunkStart + gcm.NonceSize()]
            ciphertext := encryptedFile[chunkStart + gcm.NonceSize() : chunkEnd]
            authTag := encryptedFile[chunkEnd : chunkEnd + gcm.Overhead()]
    
            decryptedChunk, err := gcm.Open(nil, nonce, ciphertext, authTag)
            if err != nil {
                return nil, err
            }
    
            plaintext = append(plaintext, decryptedChunk...)
        }
    
        return plaintext, nil
    }
    

    如果您想使用不同的包来满足您的加密和解密需求,请检查 ChaCha20-Poly1305 认证加密算法。

    【讨论】:

      最近更新 更多