Сколько существует форматов ключей шифрования и подписи? Ответ на этот вопрос — очень много. Почему? Ну, в наши дни мы можем обернуть ключ шифрования в формат JSON, который предоставляет дополнительную информацию о том, как можно использовать ключ шифрования.
Для компьютера эти ключи — всего лишь куча единиц и нулей, но для людей мы не так хорошо интерпретируем двоичный код. Два распространенных формата — DER (двоичный) и PEM (Base64). В шестнадцатеричном представлении DER выглядит примерно так [here]:
Формат PEM немного более структурирован, имеет специальный заголовок и нижний колонтитул, а также текст Base64 между ними:
Ни один из этих форматов файлов не дает много информации о деталях ключа, таких как его идентификатор, тип используемого шифрования и так далее. Поэтому формат JSON часто используется для просмотра ключа, и Google Tink — отличное место для просмотра ключа. С его помощью мы можем определить симметричный ключ, где мы указываем ключ и ID, а затем определяем тип ключа (поскольку мы можем использовать ряд методов шифрования). В следующем примере мы используем ключ AES GCM: [link]
{
"primaryKeyId": 1331912396,
"key": [{
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.AesGcmKey",
"keyMaterialType": "SYMMETRIC",
"value": "GhBpskWWTrE27e2w67X4TzfS"
},
"outputPrefixType": "TINK",
"keyId": 1331912396,
"status": "ENABLED"
}]
}
Ключ — "GhBpskWWTrE27e2w67X4TzfS". Шестнадцатеричный формат:
1A1069B245964EB136EDEDB0EBB5F84F37D2
который состоит из 36 шестнадцатеричных символов, что составляет 144 бита. Это дает 128 бит для ключа и несколько дополнительных битов для некоторых параметров.
Для MAC (Message Authentication Code) мы используем общий секретный ключ, а затем можем использовать его для проверки подписи сообщения [here]. Опять же, в этом случае мы генерируем 128-битный ключ AES GCM [here]:
{
"primaryKeyId": 1331912396,
"key": [{
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.AesGcmKey",
"keyMaterialType": "SYMMETRIC",
"value": "GhBpskWWTrE27e2w67X4TzfS"
},
"outputPrefixType": "TINK",
"keyId": 1331912396,
"status": "ENABLED"
}]
}
При цифровой подписи мы используем пару ключей (открытый ключ и закрытый ключ). Закрытый ключ используется для подписи сообщения, а открытый ключ подтверждает подписывающего. В этом случае мы создаем пару ключей Elliptic Curve на стороне отправителя [link]:
{
“primaryKeyId”: 438545957,
“key”: [{
“keyData”: {
“typeUrl”: “type.googleapis.com/google.crypto.tink.EcdsaPrivateKey”,
“keyMaterialType”: “ASYMMETRIC_PRIVATE”,
“value”: “Ek0SBggDEAIYAhohAP4v0pziVF9He/fn8BgApUHOu2Y1TkMcejrYC4U24M3xIiBAf0AIU72H5uVIP1S6ULGLaDf4td3/RIb4F58z2Md/khogJsuTDxaY/Q0CmENKlTQIOCXEZ+qvdAW0Rkvix6Wehl4=”
},
“outputPrefixType”: “TINK”,
“keyId”: 438545957,
“status”: “ENABLED”
}]
}
Затем мы извлекаем открытый ключ для подтверждения подписи:
{
“primaryKeyId”: 438545957,
“key”: [{
“keyData”: {
“typeUrl”: “type.googleapis.com/google.crypto.tink.EcdsaPublicKey”,
“keyMaterialType”: “ASYMMETRIC_PUBLIC”,
“value”: “EgYIAxACGAIaIQD+L9Kc4lRfR3v35/AYAKVBzrtmNU5DHHo62AuFNuDN8SIgQH9ACFO9h+blSD9UulCxi2g3+LXd/0SG+BefM9jHf5I=”
},
“outputPrefixType”: “TINK”,
“keyId”: 438545957,
“status”: “ENABLED”
}]
}
Шестнадцатеричный формат этого ключа — 12060803100218021A2100FE2FD29CE2545F477BF7E7F01800A541CEBB66354E431C7A3AD80B8536E0CDF12220407F400853BD87E6E5483F54BA50B18B6837F8B5DDFF4486F8179F33D8C77F92, что составляет 154 шестнадцатеричных символа (616 бит — которые состоят из 512-битного открытого ключа и нескольких дополнительных байтов для определения формата ключа).
И во многих приложениях мы используем гибридный подход, когда мы можем защитить симметричный ключ с помощью пары ключей. В следующем примере мы используем шифрование ECIES для защиты создаваемого нами симметричного ключа, а затем используем открытый ключ [link]. Закрытый ключ затем используется для расшифровки симметричного ключа:
{
“primaryKeyId”: 1992984960,
“key”: [{
“keyData”: {
“typeUrl”: “type.googleapis.com/google.crypto.tink.EciesAeadHkdfPublicKey”,
“keyMaterialType”: “ASYMMETRIC_PUBLIC”,
“value”: “EkQKBAgCEAMSOhI4CjB0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5jcnlwdG8udGluay5BZXNHY21LZXkSAhAQGAEYARohAOaHVTjvjhpGaHv5mhuXz3Nc+Mb7RE5sMyAsv7YCB8UjIiAOaSLbqRE7ddVM14kWiNoPWB/U2MNluwLlAjw39zwAlw==”
},
“outputPrefixType”: “TINK”,
“keyId”: 1992984960,
“status”: “ENABLED”
}]
}
И существует метод, который позволяет аутентифицировать шифрование с использованием дополнительных данных, таких как порядковый номер пакета данных или используемый TCP-порт. Это называется аутентифицированным шифрованием со связанными данными (AEAD), и вот пример ключа, использующего AES-SIV [here]:
{
"primaryKeyId": 1428191678,
"key": [{
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.AesSivKey",
"keyMaterialType": "SYMMETRIC",
"value": "EkAFkhmlhYkmClmpz/vGzojJVgA/IQIMSty7rL8TXxyu9m/W0ZtzCddmSLFj7r8V/R0CywJ89KxdMVzdR+GDQH2w"
},
"outputPrefixType": "TINK",
"keyId": 1428191678,
"status": "ENABLED"
}]
}
Итак, вот и все, ваши ключи шифрования можно просматривать в JSON.
Давайте посмотрим на создание ключа для AES, DHKEM (Hybrid ML-KEM), ECDSA, ECIES, Ed25519, HKDF, HMAC, JWT, RSA PKCS#1 v1.5, RSA PSS и XChaCha20:
Для этого мы можем использовать tinkey для запуска:
$ java -jar "tinkey_deploy.jar" create-keyset - key-template AES128_EAX - out-format JSON - out 1.json
$ cat 1.json
{"primaryKeyId":2180785869,"key":
[{"keyData":{
"typeUrl":"type.googleapis.com_google.crypto.tink.AesEaxKey",
"value":"EgIIEBoQkkUmFOG1mkQFBTuuLyy6Mw==",
"keyMaterialType":"SYMMETRIC"},
"status":"ENABLED",
"keyId":2180785869,
"outputPrefixType":"TINK"}]
}
Код здесь:
Google Tink with Go (PRF)Для AES_EAX [here]:
{
"primaryKeyId": 1396503152,
"key": [
{
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.AesEaxKey",
"value": "EgIIEBoQ6RkAIuX/Atj/SkqcpswobA==",
"keyMaterialType": "SYMMETRIC"
},
"status": "ENABLED",
"keyId": 1396503152,
"outputPrefixType": "TINK"
}
]
}
Для ChaCha20 [here]:
{
"primaryKeyId": 1961123280,
"key": [
{
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.ChaCha20Poly1305Key",
"value": "EiBGO18rw7WEmiWmDhWtdeLh9yifxqh8ZiRkEc+w0Axaxw==",
"keyMaterialType": "SYMMETRIC"
},
"status": "ENABLED",
"keyId": 1961123280,
"outputPrefixType": "TINK"
}
]
}
Для DH-ML-KEM [here]:
{
"primaryKeyId": 471886363,
"key": [
{
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.HpkePrivateKey",
"value": "EksSBggCEAEYARpBBEPwo/feGpb3vlP+PqHmfNcyx4MFiUhmgI6UTlYeOE3CuPlPEr29y10xpEnU7Rbz/68rC/DKtIQgj9wxSqy2jIAaINRX8U+vDAMHohP7pB0eL4APBLGucNXmrNQ/LlKTXMde",
"keyMaterialType": "ASYMMETRIC_PRIVATE"
},
"status": "ENABLED",
"keyId": 471886363,
"outputPrefixType": "TINK"
}
]
}
Для ECDSA [here]:
{
"primaryKeyId": 1264604753,
"key": [
{
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.EcdsaPrivateKey",
"value": "Ek4SBggDEAIYAhohADjXTBYypwLxLyv16U1Cjc65bOThbbuy6fLUW/KRPW2+IiEAeNVl+SBSsCTcan65Ak/INw0LxdA7QjxYjhlUwV9jv18aIQDt6E9K9l2uTaMqrptTL+fwMsy4jErqNQrzTLsYB242GQ==",
"keyMaterialType": "ASYMMETRIC_PRIVATE"
},
"status": "ENABLED",
"keyId": 1264604753,
"outputPrefixType": "TINK"
}
]
}
Для Ed25519 [here]:
{
"primaryKeyId": 548270440,
"key": [
{
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.Ed25519PrivateKey",
"value": "EiBgPvg/MifqxLPxSSJNDX2sVf1vmsXTqA+adiDVHI5LaBoiEiBN/JwLTuGB1fan3TCMBLXPx6aeMhNQ7t/tpJXltxpZiQ==",
"keyMaterialType": "ASYMMETRIC_PRIVATE"
},
"status": "ENABLED",
"keyId": 548270440,
"outputPrefixType": "TINK"
}
]
}
Для RSA PSS [here]:
{
"primaryKeyId": 744063254,
"key": [
{
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.RsaSsaPssPrivateKey",
"value": "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",
"keyMaterialType": "ASYMMETRIC_PRIVATE"
},
"status": "ENABLED",
"keyId": 744063254,
"outputPrefixType": "TINK"
}
]
}