大佬教程收集整理的这篇文章主要介绍了如何在 Kotlin 中解密 AES/CBC 加密字符串?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我在服务器上有这个 Python 方法来将字符串加密为字节 (AES/CBC)。
class AESCipher(object,key):
def __init__(self,key):
self.bs = AEs.BLOCK_SIZE
self.key = hashlib.sha256(key.encode()).digest()
def encrypt(self,raw):
raw = self._pad(raw)
iv = Random.new().read(AEs.BLOCK_SIZE)
cipher = AEs.new(self.key,AEs.MODE_CBC,iv)
return base64.b64encode(iv + cipher.encrypt(raw.encode()))
def decrypt(self,enC):
enc = base64.b64decode(enC)
iv = enc[:AEs.BLOCK_SIZE]
cipher = AEs.new(self.key,iv)
return self._unpad(cipher.decrypt(enc[AEs.BLOCK_SIZE:])).decode('utf-8')
def _pad(self,s):
return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)
encrypt() 的输出在 bytes
中是这样的:b'PMgMOkBkciIKfWy/DfntVMyAcKtVsM8LwEwnTYE5IXY='
我想将其存储到数据库中,并通过 API 将其作为字符串发送到 Kotlin。在那里我想通过相同的共享密钥解密它。
ByteArray
?我的理论是我必须在数据库中将字节存储为 base64 字符串。 另一方面,我必须将字符串作为 base64 解码为字节。这种方法是否正确?使用下面的代码,加密/解密会像这样端到端地工作吗?
fun decrypt(context:Context,dataToDecrypt: ByteArray): ByteArray {
val cipher = Cipher.geTinstance("AES/CBC/PKCS5padding")
val ivSpec = IvParameterSpec(getSavedInitializationVector(context))
cipher.init(Cipher.DECRYPT_MODE,getSavedSecretKey(context),ivSpeC)
val cipherText = cipher.doFinal(dataToDecrypt)
val sb = StringBuilder()
for (b in cipherText) {
sb.append(b.tochar())
}
return cipherText
}
fun getSavedSecretKey(context: Context): SecretKey {
val sharedPref = PreferenceManager.getDefaultSharedPreferences(context)
val strSecretKey = sharedPref.getString("secret_key","")
val bytes = androID.util.base64.decode(strSecretKey,androID.util.base64.DEFAulT)
val ois = ObjecTinputStream(ByteArrayinputStream(bytes))
val secretKey = ois.readobject() as SecretKey
return secretKey
}
fun getSavedInitializationVector(context: Context) : ByteArray {
val sharedPref = PreferenceManager.getDefaultSharedPreferences(context)
val StrinitializationVector = sharedPref.getString("initialization_vector","")
val bytes = androID.util.base64.decode(StrinitializationVector,androID.util.base64.DEFAulT)
val ois = ObjecTinputStream(ByteArrayinputStream(bytes))
val initializationVector = ois.readobject() as ByteArray
return initializationVector
}
更新
我已尝试删除 Base64 以消除建议的内存开销。
蟒蛇:
def encrypt(self,iv)
return iv + cipher.encrypt(raw.encode())
所以这不再可能。
enc = AESCipher('abc').encrypt("mylife")
value_to_save_in_db = enc.decode("utf8")
所以我需要找到一种方法将字节数组直接存储在数据库中。我想我应该能够做到这一点。但是,如何将字节数组作为 JsON 的一部分通过 API 发送到 AndroID 设备仍然存在一些挑战。我想我必须再次将其转换为 Base64 字符串。不知道在那种情况下我是否得到了什么......
以下 Kotlin 代码:
val decrypted = decrypt("bLeoKMQtUbNOzJbvEkL2gNhjF+qQ/ZK84f2ADu8xyUFme6uBhNYqvEherF/RRO9YRImz5Y04/ll+T07kqv+ExQ==");
println(decrypted);
解密 Python 代码的密文。这里的 decrypt()
是:
fun decrypt(dataToDecryptB64 : String) : String {
// Base64 decode Python data
val dataToDecrypt = Base64.getDecoder().decode(dataToDecryptB64)
// Separate IV and Ciphertext
val ivBytes = ByteArray(16)
val cipherBytes = ByteArray(dataToDecrypt.size - ivBytes.sizE)
System.arraycopy(dataToDecrypt,ivBytes,ivBytes.sizE)
System.arraycopy(dataToDecrypt,ivBytes.size,cipherBytes,cipherBytes.sizE)
// Derive key
val keyBytes = messageDigest.geTinstance("SHA256").digest("abc".toByteArray(CharsetS.UTF_8))
// Decrypt
val cipher = Cipher.geTinstance("AES/CBC/PKCS5PADDING")
cipher.init(Cipher.DECRYPT_MODE,SecretKeySpec(keyBytes,"AES"),IvParameterSpec(ivBytes))
val cipherText = cipher.doFinal(cipherBytes)
return String(cipherText,Charsets.ISO_8859_1)
}
为此,密文是使用发布的 Python 类 AESCipher
生成的,如下所示:
plaintext = 'The quick brown fox jumps over the lazy dog'
cipher = AESCipher('abc')
ciphertext = cipher.encrypt(plaintext)
print(ciphertext.decode('utf8')) # Base64 String,which can be stored e.g. in a DB
我应用了最初发布的 Python 实现,该实现使用 SHA256 导出密钥。但是,如果密钥是从密码派生的,出于安全原因,不是 SHA256,而是可靠的密钥派生函数,例如应使用 Argon2 或 PBKDF2。
Kotlin 代码首先对 Python 数据进行 Base64 解码,然后将 IV 和实际密文分开。然后,通过生成密码的 SHA256 哈希来派生密钥。最后解密数据。
当前 Python 代码 Base64 对数据进行编码,以便将其作为字符串存储在数据库中。或者,可以修改 Python 代码,以便不执行 Base64 编码,并且可以存储原始数据(这需要更少的内存,Base64 开销:33%)。
根据选择的解决方案,Kotlin 代码可能需要也可能不需要对数据进行 Base64 解码。
以上是大佬教程为你收集整理的如何在 Kotlin 中解密 AES/CBC 加密字符串?全部内容,希望文章能够帮你解决如何在 Kotlin 中解密 AES/CBC 加密字符串?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。