使用 Google Tink 加密间歇性损坏数据

Posted

技术标签:

【中文标题】使用 Google Tink 加密间歇性损坏数据【英文标题】:Intermittently corrupted data with Google Tink encryption 【发布时间】:2021-10-06 02:59:47 【问题描述】:

我正在调查在我当前的 android 项目中使用com.google.crypto.tink:tink-android:1.6.1

我加密的数据包括我用于远程 API 调用的 OAuth2 访问令牌/刷新令牌,例如访问令牌是我的授权 HTTP 标头的不记名令牌。

我担心我的加密/解密逻辑出现错误,因为我遇到了无法刷新令牌的间歇性问题。来自服务器的错误

"error_description":"unknown, invalid, or expired refresh token","error":"invalid_grant"

刷新令牌不会过期,因为它会持续 24 小时。

我初始化 Tink 的代码如下:-

private fun manageTink() 
    try 
        AeadConfig.register()
        authenticatedEncryption = generateNewKeysetHandle().getPrimitive(Aead::class.java)
     catch (e: GeneralSecurityException) 
        throw RuntimeException(e)
     catch (e: IOException) 
        throw RuntimeException(e)
    


@Throws(IOException::class, GeneralSecurityException::class)
private fun generateNewKeysetHandle(): KeysetHandle =
    AndroidKeysetManager
        .Builder()
        .withSharedPref(this, TINK_KEYSET_NAME, PREF_FILE_NAME)
        .withKeyTemplate(KeyTemplates.get("AES256_GCM"))
        .withMasterKeyUri(MASTER_KEY_URI)
        .build()
        .keysetHandle

这是我的加密/解密代码

import android.util.Base64
import com.google.crypto.tink.Aead
import javax.inject.Inject

const val BASE64_ENCODE_SETTINGS = Base64.NO_WRAP or Base64.NO_PADDING

data class Security @Inject constructor(private val authenticatedEncryption: Aead) 

    fun conceal(plainText: String, associatedData: String): String 
        val plain64 = Base64.encode(plainText.encodeToByteArray(), BASE64_ENCODE_SETTINGS)
        val associated64 = Base64.encode(associatedData.encodeToByteArray(), BASE64_ENCODE_SETTINGS)
        val encrypted: ByteArray? = authenticatedEncryption.encrypt(plain64, associated64)

        return Base64.encodeToString(encrypted, BASE64_ENCODE_SETTINGS)
    

    fun reveal(encrypted64: String, associatedData: String): String 
        val encrypted = Base64.decode(encrypted64.encodeToByteArray(), BASE64_ENCODE_SETTINGS)
        val associated64 = Base64.encode(associatedData.encodeToByteArray(), BASE64_ENCODE_SETTINGS)
        val decrypted: ByteArray? = authenticatedEncryption.decrypt(encrypted, associated64)

        return String(Base64.decode(decrypted, BASE64_ENCODE_SETTINGS))
    

可能是使用 Base64 编码/解码的问题吗? 我的错在哪里?

【问题讨论】:

请注意——为什么在加密之前对明文和 aad 数据进行 Base64 编码? @MichaelFehr,我使用 Base64 编码,因为我的某些数据可能包含无法打印的字符。只是为了安全起见。这引起了我的问题,因为我的 Base64 标志确实包含 URL_SAFE,它在编码和解码之间“破坏/更改”数据。 您能否在没有 OAuth2 令牌的情况下重现间歇性加密/解密问题?如果不是,也许它毕竟是令牌(以某种不可预见的方式)。间歇性的事情闻起来有点像令牌验证相关的问题。 @Topaco,我的问题只在处理令牌时出现......我相信你是正确的令牌本身是无效的,Tink 没有引起任何问题 【参考方案1】:

如果 Tink 可以解密您的令牌,那么问题应该出在您的令牌/编码而不是 Tink(它使用经过身份验证的加密,因此您可以保证您加密的字节将是您解密的字节, 否则会出错)。

还要解决评论中的问题:Tink 将愉快地加密和解密任何字节字符串(相关数据也可以是任何字节字符串),而不关心它们是否可打印甚至是有效的 Unicode。但是,如果要将 Tink 的输出用作字符串,则必须对其进行 base64 编码,因为它将是均匀随机分布的字节,即很有可能包含无效的 Unicode 和不可打印的字符。

【讨论】:

以上是关于使用 Google Tink 加密间歇性损坏数据的主要内容,如果未能解决你的问题,请参考以下文章

来自 pdf.js 的间歇性“无效或损坏的 PDF 文件”

如何在 C++ 中使用 Tink 从安全的 websocket 中读取数据

Canvas .toDataURL() 返回部分损坏的图像

通过代理读取器加载的存储中不一致的数据损坏

Google Cloud Platform 上的 ndb 查询间歇性地不返回任何内容

Apache Commons Net FTP 正在上传损坏的文件