【发布时间】:2019-07-23 11:40:06
【问题描述】:
我正在尝试加密来自 glide 的输入流。
我将输入流转换为字节数组并在我的加密方法中传递:
fun encrypt(input: ByteArray): ByteArray {
Log.e("TAG", "inputsize: ${input.size}")
val iv = ByteArray(KeyStoreHelper.IV_SIZE)
val secureRandom = SecureRandom()
secureRandom.nextBytes(iv)
val c = Cipher.getInstance(KeyStoreHelper.AES_MODE)
c.init(Cipher.ENCRYPT_MODE, getKey(), GCMParameterSpec(KeyStoreHelper.GCM_SIZE, iv))
Log.e("TAG", "outputsize: ${c.getOutputSize(input.size)}")
val encodedBytes = c.doFinal(input)
Log.e("TAG", "encodedBytesSize: ${encodedBytes.size}")
val byteBuffer = ByteBuffer.allocate( iv.size + encodedBytes.size)
byteBuffer.put(iv)
byteBuffer.put(encodedBytes)
Log.e("TAG", "byteBuffer: ${byteBuffer.array().size}")
return byteBuffer.array()
}
日志如下所示:
inputsize: 750683
outputsize: 750699
encodedBytesSize: 95339
byteBuffer: 95351
如您所见,加密的图像字节数组太小了,我不明白为什么 - 如果我尝试加密字符串或更小的图像(大约 100kb-200kb),它就像一个魅力。
感谢您帮助我!
亲切的问候 汤姆
【问题讨论】:
-
有趣,这可能是一个错误。当然,首先读取数组中所有内容的想法是个坏主意,但
doFinal不应该这样做。请说明使用的运行时和库(主要是为密码配置的提供程序(打印出c.getProvider().toString())。 -
嗨,马丁,感谢您的回复!有什么比“首先读取数组中的所有内容”更好的做法 - 很难找到一个好的、有效的、相对最新的示例...... c.getProvider().toString() 给我以下内容:
AndroidKeyStoreBCWorkaround version 1.0 -
一般你可以使用
CipherInputStream和CipherOutputStream,但首先检查它是否适用于Android上的GCM; 之后,这些流经常被改装以与 GCM 兼容。 -
通常您将
CipherOutputStream连接到另一个流。您可以先将其写入该流。随机数也可以通过其他方式计算或传输,因此将它作为密文的一部分是没有意义的(顺便说一下,在我看来,标签也不应该是密文的一部分 - 至少不在API)。 -
酷。 Kudo 使用 Android 密钥库、GCM 和一个独特的随机数。顺便说一句,您的
getKey代码需要紧急重构。 getter 不应该在幕后做所有这些事情,而且您不应该首先创建诸如此类的包罗万象的方法。将其拆分为密钥生成、检索和算法初始化。这段代码当然不遵守最少意外原则。
标签: android encryption kotlin aes