快速字符串中的AES256加密不匹配

时间:2021-03-23 05:25:38

标签: android ios swift xcode encryption

我们在 Java/Android 中使用过

private const val secretKey = "1f23456d2d014be5"
private const val salt = "a986e0093328765e"
private const val ivKey = "9898989890KJHYTR"

fun passwordEncryptMethod(stringToEncrypt: String): String? {
    var encryptedText = ""
    try {
        
        val iv: ByteArray = ivKey.toByteArray()
        val ivspec = IvParameterSpec(iv)

        val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256")
        val spec: KeySpec = PBEKeySpec(
            secretKey.toCharArray(),
            salt.toByteArray(),
            65536,
            256
        )

        val tmp = factory.generateSecret(spec)
        val secretKey = SecretKeySpec(tmp.encoded, "AES")
        val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec)

        val encryptedByte: ByteArray =
            cipher.doFinal(stringToEncrypt.toByteArray(charset("UTF-8")))
        encryptedText = Base64.encodeToString(encryptedByte, Base64.NO_WRAP)

        return encryptedText

    } catch (e: Exception) {
        Log.i("Error encrypting:", e.message ?: "")
    }
    return encryptedText
}

在 iOS Swift 中,我使用了 . https://gist.github.com/hfossli/7165dc023a10046e2322b0ce74c596f8

方法 1 使用 CCKeyDerivationPBKDF 和 CCCrypt

 let digest = "StringToEncrypt".data(using: .utf8)!
        let password = "1f23456d2d014be5".data(using: .utf8)!
        let salt = "a986e0093328765e".data(using: String.Encoding.utf8)!//AES256.randomSalt()
        let iv = "9898989890KJHYTR".data(using: String.Encoding.utf8)!//AES256.randomIv()
        let key = try AES256.createKey(password: digest, salt: salt)
        var aes = try AES256(key: key, iv: iv)
        let encrypted = try aes.encrypt(password)
        print( #function, (encrypted.base64EncodedString()))

//辅助函数

 static func createKey(password: Data, salt: Data) throws -> Data {
        let length = kCCKeySizeAES256
        var status = Int32(0)
        var derivedBytes = [UInt8](repeating: 0, count: length)
        password.withUnsafeBytes { (passwordBytes: UnsafePointer<Int8>!) in
            salt.withUnsafeBytes { (saltBytes: UnsafePointer<UInt8>!) in
                status = CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2),                  // algorithm
                                              passwordBytes,                                // password
                                              password.count,                               // passwordLen
                                              saltBytes,                                    // salt
                                              salt.count,                                   // saltLen
                                              CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256),   // prf
                                              65536,                                        // rounds
                                              &derivedBytes,                                // derivedKey
                                              length)                                       // derivedKeyLen
            }
        }
        guard status == 0 else {
            throw Error.keyGeneration(status: Int(status))
        }
        return Data(bytes: UnsafePointer<UInt8>(derivedBytes), count: length)
    }
mutating func encrypt(_ digest: Data) throws -> Data {
    return try crypt(input: digest, operation: CCOperation(kCCEncrypt))
}

mutating func decrypt(_ encrypted: Data) throws -> Data {
    return try crypt(input: encrypted, operation: CCOperation(kCCDecrypt))
}

private mutating func crypt(input: Data, operation: CCOperation) throws -> Data {
    var outLength = Int(0)
    var outBytes = [UInt8](repeating: 0, count: input.count + kCCBlockSizeAES128)
   // var status: CCCryptorStatus = CCCryptorStatus(kCCSuccess)
    
    
    
    var keyValue = self.key
    
    let status: CCCryptorStatus =
        input.withUnsafeBytes {encryptedBytes in
        iv.withUnsafeBytes {ivBytes in
            keyValue.withUnsafeMutableBytes {keyBytes in
                CCCrypt( // Stateless, one-shot encrypt operation
                    CCOperation(kCCEncrypt),                // op: CCOperation
                    CCAlgorithm(kCCAlgorithmAES),           // alg: CCAlgorithm
                    CCOptions(kCCOptionPKCS7Padding),                                // options: CCOptions
                    keyBytes.baseAddress,                   // key: the "password"
                    key.count,                              // keyLength: the "password" size
                    ivBytes.baseAddress,                // iv: Initialization Vector
                    encryptedBytes.baseAddress,                  // dataIn: Data to encrypt bytes
                    input.count,                    // dataInLength: Data to encrypt size
                   &outBytes, //bufferBytes.baseAddress! + kCCBlockSizeAES128, // dataOut: encrypted Data buffer
                    outBytes.count,                             // dataOutAvailable: encrypted Data buffer size
                    &outLength                   // dataOutMoved: the number of bytes written
                )
            }
        }
    }
    
    
    

    guard status == kCCSuccess else {
        throw Error.cryptoFailed(status: status)
    }
    return Data(bytes: UnsafePointer<UInt8>(outBytes), count: outLength)
}

方法 2 基于此链接 How to use CommonCrypto for PBKDF2 in Swift 2 & 3

但是我在两个平台上都得到了不同的 base64 编码字符串。请帮忙。

0 个答案:

没有答案