- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 Tink 中,可以将明文 key 集作为 json 加载和编写。下面是一个无效的示例:
{
"primaryKeyId": 2800579,
"key": [
{
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.AesGcmKey",
"value": "ODA9eJX9wcAGwZocL0Jym==",
"keyMaterialType": "SYMMETRIC"
},
"status": "ENABLED",
"keyId": 2800579,
"outputPrefixType": "TINK"
}
]
}
我的问题是 - 是否可以将您自己的值插入到各种键/值对中以获得另一个有效的键集?我对此进行了试验,但没有取得多大成功——主要是因为“值”键提示 INVALID_ARGUMENT: Could not parse key_data.value as key type 'type.googleapis.com/google.crypto.tink. AesGcmKey'
知道什么是有效“值”吗?
最佳答案
首先,发布的代码片段中value字段的Base64字符串是无效的,可能是复制/粘贴错误。
以下 Python 代码使用 Tink version 1.5.0并为 AES-256/GCM 创建 key 集并将其显示为 JSON:
import io
from tink import aead
from tink import tink_config
from tink import JsonKeysetWriter
from tink import new_keyset_handle
from tink import cleartext_keyset_handle
tink_config.register()
key_template = aead.aead_key_templates.AES256_GCM
keyset_handle = new_keyset_handle(key_template)
string_out = io.StringIO()
writer = JsonKeysetWriter(string_out)
cleartext_keyset_handle.write(writer, keyset_handle)
serialized_keyset = string_out.getvalue();
print(serialized_keyset);
结果类似于您发布的 KeySet,例如:
{
"primaryKeyId": 1794775293,
"key": [
{
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.AesGcmKey",
"value": "GiD5ojApaIM2MRpPhGf5sVMhxeA6NE5KjdzUxsJ0ChH/JA==",
"keyMaterialType": "SYMMETRIC"
},
"status": "ENABLED",
"keyId": 1794775293,
"outputPrefixType": "TINK"
}
]
}
我还没有找到描述一般结构或值 字段的文档,但比较不同算法生成的 KeySet 可以得出结论。如果 value 是十六进制编码,则结果是:
1a20f9a23029688336311a4f8467f9b15321c5e03a344e4a8ddcd4c6c2740a11ff24
对于 AES-256/GCM,它有 34 个字节,其中最后 32 个字节是实际 key 。开头是算法的特征,第二个字节表示 key 的大小,例如0x1a10 用于 AES-128/GCM,0x1a20 用于 AES-256/GCM 或 0x1220 用于 ChaCha20Poly1305(但可能更复杂,具体取决于算法).
为AES-256/GCM使用自定义 key ,例如
000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
前置0x1a20,Base64编码结果:
GiAAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHw==
并应用此值而不是上述 KeySet 中的旧值。
修改后的KeySet可以按如下方式加载并用于加密:
from tink import JsonKeysetReader
from tink import cleartext_keyset_handle
serialized_keyset = '''
{
"primaryKeyId": 1794775293,
"key": [
{
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.AesGcmKey",
"value": "GiAAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHw==",
"keyMaterialType": "SYMMETRIC"
},
"status": "ENABLED",
"keyId": 1794775293,
"outputPrefixType": "TINK"
}
]
}
'''
reader = JsonKeysetReader(serialized_keyset)
keyset_handle = cleartext_keyset_handle.read(reader)
plaintext = b'The quick brown fox jumps over the lazy dog'
aead_primitive = keyset_handle.primitive(aead.Aead)
tink_ciphertext = aead_primitive.encrypt(plaintext, b'')
KeySet 和示例 key 0001...1e1f 之间的关系可以通过使用示例 key 没有 Tink 解密生成的密文来验证,例如使用 PyCryptodome。
Tink Wire Format, Crypto Formats 中描述了 Tink 密文的格式.第一个字节指定版本,接下来的 4 个字节是 key ID,然后是实际数据。
对于 GCM,实际数据的格式为 nonce(12 字节)||密文||标记(16 字节)。然后可以使用(使用 PyCryptodome)进行解密:
from Crypto.Cipher import AES
key = bytes.fromhex('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f')
prefix = tink_ciphertext[:5]
nonce = tink_ciphertext[5:5 + 12]
ciphertext = tink_ciphertext[5 + 12:-16]
tag = tink_ciphertext[-16:]
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
cipher.update(b'')
decryptedText = cipher.decrypt_and_verify(ciphertext, tag)
print(decryptedText.decode('utf-8')) # The quick brown fox jumps over the lazy dog
证明示例 key 0001...1e1f 已正确集成到 KeySet 中。
关于python - 如何将有效值传入 cleartext_keyset_json 以创建 Tink key ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67320913/
我是一名优秀的程序员,十分优秀!