iOS CryptoSwift AES 加密到 Python 解密有效 - 但不是相反
iOS CryptoSwift AES Encryption to Python Decryption works - but not the inverse
我正在使用 CryptoSwift 1.4.1、iOS 15.2、PyCryptodome 3.12.0 和 XCode 13.2.1 来加密我发送到 Raspberry Pi Linux 设备通过 BLE。它在 iOS 加密消息并将其发送到 Raspberry Pi 时起作用。 Pi 可以成功解密它。现在我想做相反的事情,在 Pi 上加密一条消息,然后让 iOS 应用程序读取和解密它。但是,这不起作用,解密后的值不是我在 Pi 上加密的消息。
工作 iOS 加密:
func aesEncrypt(stringToEncrypt: String, key: Array<UInt8>, iv: Array<UInt8>) throws -> String {
let data = stringToEncrypt.data(using: String.Encoding.utf8)
let encrypted = try AES(key: key, blockMode: CFB(iv: iv), padding: .noPadding).encrypt((data?.bytes)!)
return encrypted.toHexString()
}
let ivString = "4198816658388141"
let keyString = "9004786896524916"
let key = [UInt8](keyString.utf8)
let iv = [UInt8](ivString.utf8)
let encryptedSsid = try! aesEncrypt(stringToEncrypt: ssid!, key: key, iv: iv)
正在 Raspberry Pi 解密 Python:
KEY = b'9004786896524916'
IV = b'4198816658388141'
MODE = AES.MODE_CFB
def decrypt(key, iv, encrypted_text):
logger.info(f"Encrypted: {encrypted_text}")
aes = AES.new(key, MODE, iv, segment_size=128)
encrypted_text_bytes = binascii.a2b_hex(encrypted_text)
decrypted_text = aes.decrypt(encrypted_text_bytes).decode("utf-8")
logger.info(f"Decrypted: {decrypted_text}")
return decrypted_text
我尝试使用以下代码在 Pi 上加密消息:
KEY = b'9004786896524916'
IV = b'4198816658388141'
MODE = AES.MODE_CFB
def encrypt(key, decrypted_text):
# Create cipher object and encrypt the data
logger.info(f"Decrypted: {decrypted_text}")
cipher = AES.new(key, MODE, segment_size=128) # Create a AES cipher object with the key using the mode CBC
#encrypted_text = cipher.encrypt(pad(decrypted_text, AES.block_size)) # Pad the input data and then encrypt
encrypted_text = cipher.encrypt(decrypted_text) # Pad the input data and then encrypt
logger.info(f"Encrypted: {encrypted_text}")
return encrypted_text
...
encrypt(KEY, returnString('utf-8'))
但是,iOS 应用无法使用此方法正确解密:
func aesDecrypt(stringToDecrypt: String, key: Array<UInt8>, iv: Array<UInt8>) throws -> String {
let data = stringToDecrypt.data(using: String.Encoding.utf8)
let decrypted = try AES(key: key, blockMode: CFB(iv: iv), padding: .noPadding).decrypt((data?.bytes)!)
return decrypted.toHexString()
}
let ivString = "4198816658388141"
let keyString = "9004786896524916"
let key = [UInt8](keyString.utf8)
let iv = [UInt8](ivString.utf8)
var message = try! aesDecrypt(stringToDecrypt: charString, key: key, iv: iv)
当消息在 Pi 上加密时,我如何才能在 iOS 应用程序中正常解密?谢谢。
在 encrypt()
方法中不考虑 IV。与 aesEncrypt()
一样,创建 AES 对象时必须传递和使用 IV。
此外,编码中存在错误:明文必须是 UTF8 编码,密文必须是十六进制编码:
from Crypto.Cipher import AES
import binascii
def encrypt(key, iv, plaintext):
cipher = AES.new(key, MODE, iv, segment_size=128)
plaintext_bytes = plaintext.encode("utf-8")
ciphertext = cipher.encrypt(plaintext_bytes)
ciphertext_hex = binascii.b2a_hex(ciphertext)
return ciphertext_hex
此函数与decrypt()
对应,即encrypt()
可用于生成密文,密文可用decrypt()
(或aesDecrypt()
)解密。
在 iOS 代码中有两个错误,都与编码有关:密文不能是 UTF8 编码,而是十六进制解码。并且解密后的数据不能是十六进制编码,而是UTF-8解码。
可能的解决方法是:
func aesDecrypt(stringToDecrypt: String, key: Array<UInt8>, iv: Array<UInt8>) throws -> String {
let data = Array<UInt8>(hex: stringToDecrypt)
let decrypted = try AES(key: key, blockMode: CFB(iv: iv), padding: .noPadding).decrypt(data)
return String(bytes: decrypted, encoding: .utf8)!
}
此函数与aesEncrypt()
对应,即aesDecrypt()
可用于解密由aesEncrypt()
(或encrypt()
)生成的密文。
关于安全性:静态 IV 是不安全的。相反,应该为每次加密随机生成 IV。由于解密需要 (non-secret IV),因此它与密文一起传递(通常是串联的)。
我正在使用 CryptoSwift 1.4.1、iOS 15.2、PyCryptodome 3.12.0 和 XCode 13.2.1 来加密我发送到 Raspberry Pi Linux 设备通过 BLE。它在 iOS 加密消息并将其发送到 Raspberry Pi 时起作用。 Pi 可以成功解密它。现在我想做相反的事情,在 Pi 上加密一条消息,然后让 iOS 应用程序读取和解密它。但是,这不起作用,解密后的值不是我在 Pi 上加密的消息。
工作 iOS 加密:
func aesEncrypt(stringToEncrypt: String, key: Array<UInt8>, iv: Array<UInt8>) throws -> String {
let data = stringToEncrypt.data(using: String.Encoding.utf8)
let encrypted = try AES(key: key, blockMode: CFB(iv: iv), padding: .noPadding).encrypt((data?.bytes)!)
return encrypted.toHexString()
}
let ivString = "4198816658388141"
let keyString = "9004786896524916"
let key = [UInt8](keyString.utf8)
let iv = [UInt8](ivString.utf8)
let encryptedSsid = try! aesEncrypt(stringToEncrypt: ssid!, key: key, iv: iv)
正在 Raspberry Pi 解密 Python:
KEY = b'9004786896524916'
IV = b'4198816658388141'
MODE = AES.MODE_CFB
def decrypt(key, iv, encrypted_text):
logger.info(f"Encrypted: {encrypted_text}")
aes = AES.new(key, MODE, iv, segment_size=128)
encrypted_text_bytes = binascii.a2b_hex(encrypted_text)
decrypted_text = aes.decrypt(encrypted_text_bytes).decode("utf-8")
logger.info(f"Decrypted: {decrypted_text}")
return decrypted_text
我尝试使用以下代码在 Pi 上加密消息:
KEY = b'9004786896524916'
IV = b'4198816658388141'
MODE = AES.MODE_CFB
def encrypt(key, decrypted_text):
# Create cipher object and encrypt the data
logger.info(f"Decrypted: {decrypted_text}")
cipher = AES.new(key, MODE, segment_size=128) # Create a AES cipher object with the key using the mode CBC
#encrypted_text = cipher.encrypt(pad(decrypted_text, AES.block_size)) # Pad the input data and then encrypt
encrypted_text = cipher.encrypt(decrypted_text) # Pad the input data and then encrypt
logger.info(f"Encrypted: {encrypted_text}")
return encrypted_text
...
encrypt(KEY, returnString('utf-8'))
但是,iOS 应用无法使用此方法正确解密:
func aesDecrypt(stringToDecrypt: String, key: Array<UInt8>, iv: Array<UInt8>) throws -> String {
let data = stringToDecrypt.data(using: String.Encoding.utf8)
let decrypted = try AES(key: key, blockMode: CFB(iv: iv), padding: .noPadding).decrypt((data?.bytes)!)
return decrypted.toHexString()
}
let ivString = "4198816658388141"
let keyString = "9004786896524916"
let key = [UInt8](keyString.utf8)
let iv = [UInt8](ivString.utf8)
var message = try! aesDecrypt(stringToDecrypt: charString, key: key, iv: iv)
当消息在 Pi 上加密时,我如何才能在 iOS 应用程序中正常解密?谢谢。
在 encrypt()
方法中不考虑 IV。与 aesEncrypt()
一样,创建 AES 对象时必须传递和使用 IV。
此外,编码中存在错误:明文必须是 UTF8 编码,密文必须是十六进制编码:
from Crypto.Cipher import AES
import binascii
def encrypt(key, iv, plaintext):
cipher = AES.new(key, MODE, iv, segment_size=128)
plaintext_bytes = plaintext.encode("utf-8")
ciphertext = cipher.encrypt(plaintext_bytes)
ciphertext_hex = binascii.b2a_hex(ciphertext)
return ciphertext_hex
此函数与decrypt()
对应,即encrypt()
可用于生成密文,密文可用decrypt()
(或aesDecrypt()
)解密。
在 iOS 代码中有两个错误,都与编码有关:密文不能是 UTF8 编码,而是十六进制解码。并且解密后的数据不能是十六进制编码,而是UTF-8解码。
可能的解决方法是:
func aesDecrypt(stringToDecrypt: String, key: Array<UInt8>, iv: Array<UInt8>) throws -> String {
let data = Array<UInt8>(hex: stringToDecrypt)
let decrypted = try AES(key: key, blockMode: CFB(iv: iv), padding: .noPadding).decrypt(data)
return String(bytes: decrypted, encoding: .utf8)!
}
此函数与aesEncrypt()
对应,即aesDecrypt()
可用于解密由aesEncrypt()
(或encrypt()
)生成的密文。
关于安全性:静态 IV 是不安全的。相反,应该为每次加密随机生成 IV。由于解密需要 (non-secret IV),因此它与密文一起传递(通常是串联的)。