Swift iOS中的CommonCrypto对openssl命令行产生不同的结果

Swift iOS中的CommonCrypto对openssl命令行产生不同的结果,swift,encryption,openssl,aes,commoncrypto,Swift,Encryption,Openssl,Aes,Commoncrypto,我在我的应用程序中使用CommonCrypto对一些使用openssl加密的数据进行解密。为了测试加密,我尝试对一些示例数据进行加密,但令人惊讶的是,我的加密(即aes ecb)的输出与使用openssl命令生成的输出不同 我还尝试了其他框架,如CryptoSwift,但结果是一样的 下面是我用来加密的代码: class AESEncryptor { static func encrypt(text: String, key: String) -> String? {

我在我的应用程序中使用CommonCrypto对一些使用openssl加密的数据进行解密。为了测试加密,我尝试对一些示例数据进行加密,但令人惊讶的是,我的加密(即aes ecb)的输出与使用openssl命令生成的输出不同

我还尝试了其他框架,如CryptoSwift,但结果是一样的

下面是我用来加密的代码:

class AESEncryptor {

    static func encrypt(text: String, key: String) -> String? {

        guard let encryptingData = text.data(using: .utf8), let keyData = key.data(using: .utf8) else {
            return nil
        }

        var outLength = Int(0)
        var outBytes = [UInt8](repeating: 0, count: encryptingData.count + kCCBlockSizeAES128)
        var status: CCCryptorStatus = CCCryptorStatus(kCCSuccess)
        encryptingData.withUnsafeBytes { (encryptingBytes: UnsafePointer<UInt8>!) -> () in
            keyData.withUnsafeBytes { (keyBytes: UnsafePointer<UInt8>!) -> () in
                status = CCCrypt(CCOperation(kCCEncrypt),
                                 CCAlgorithm(kCCAlgorithmAES),            // algorithm
                    CCOptions(kCCOptionECBMode | kCCOptionPKCS7Padding),           // options
                    keyBytes,                                   // key
                    keyData.count,                                  // keylength
                    nil, //ivBytes,                                    // iv
                    encryptingBytes,                             // dataIn
                    encryptingData.count,                                // dataInLength
                    &outBytes,                                  // dataOut
                    outBytes.count,                             // dataOutAvailable
                    &outLength)                                 // dataOutMoved
            }
        }
        guard status == kCCSuccess else {
            return nil
        }

        let encryptedData =  Data(bytes: UnsafePointer<UInt8>(outBytes), count: outLength)
        return encryptedData.base64EncodedString()

    }
}
摘要为“4EBHOU+Rma34MR4iBTT04AS6rXX+Jy2U97rwC2HGmz0=”

同时,openssl命令行,输入相同:

echo -n "ThisIsASuperSecurePassword" | openssl enc -e -aes-128-ecb -K "3466306662616434373134316566393631366365346437316234353965656139" -a
(“346630666261643437313431656639363136636534643731623435365656139”是“4f0fbad47141ef9616ce4d71b459eea9”的十六进制字符串)

给我“ZPO4JNRMBZP4WXNPGKX1RUBIPNXZQE0XNQNMFPTT/Q=”

所以,我的问题是:为什么它们不一样?如何获得相同的输出


AD

第一个问题是您没有使用AES-128-EBC编码,而是使用AES-256-EBC编码。使用是因为密钥长度是256位,而不是128位

因此,如果我们使用openssl编码,并使用正确的密钥长度,我会得到:

(注意,我正在使用powershell,由于某些原因,将文本管道化到命令将添加一个CRLF,因此我将通过文件将其添加到该命令中)

我得到:

4EBHOU+Rma34MR4iBTT04AS6rXX+Jy2U97rwC2HGmz0=

这和你得到的一样

然后,对输出进行解密,再次生成纯文本:

"4ebhUO+Rma34MR4iBTT04AS6rXX+Jy2U97rwC2HGmz0=" | openssl enc -d -aes-256-ecb -K 3466306662616434373134316566393631366365346437316234353965656139 -a -p
生成输出:

这是一个超级安全的密码


如果您确实想要AES-128,则需要将密钥大小减少到128位长度。

这两种情况不尽相同;您似乎正在使用powershell,其中“abc”输出abc,然后是CRLF。不确定CRLF注释的含义。如果我将解码的结果输出到一个文件中,这两个文件是相同的,并且我在输出文件中没有看到CRLF。我只是仔细检查了我的结果,你是正确的。My的末尾有一个CRLF,这是两者之间的区别。感谢@dave_thompson_085的输入。我已经更新了我的答案,以反映相同的输出。在结尾没有换行符的情况下,我无法理解如何使用powershell管道:(
"ThisIsASuperSecurePassword" | Set-Content -NoNewLine plaintext.txt
openssl enc -e -aes-256-ecb -K 3466306662616434373134316566393631366365346437316234353965656139 -a -in plaintext.txt
"4ebhUO+Rma34MR4iBTT04AS6rXX+Jy2U97rwC2HGmz0=" | openssl enc -d -aes-256-ecb -K 3466306662616434373134316566393631366365346437316234353965656139 -a -p