Требуются разъяснения по правильному асимметричному шифрованию с использованием пакета tweetnacl с парами ключей Solana (Ed25519)

Я работаю с блокчейном Solana, который использует пары ключей Ed25519, где открытый ключ - это адрес кошелька, а секретный ключ используется для подписи сообщений в транзакциях. Я обнаружил, что некоторые из javascript-библиотек Solana (@solana / web3.js, @solana / spl-token и т. Д.) Используют некоторые структуры данных, совместимые с tweetnacl реализация .

Я решил использовать пары ключей Solana Ed25519 в моем собственном шифровании / дешифровании данных на бэкэнде, поэтому я следовал документации, но везде ( NaCl, libsodium) для Public-Key-Authenticated-Encryption они сказали, что вы можете и ДОЛЖНЫ ИСПОЛЬЗОВАТЬ открытый ключ для шифрования и секретный ключ для дешифрования и только на странице tweetnacl (https://github.com/dchest/tweetnacl-js#public-key-authenticated-encryption-box) они сказали:

      nacl.box(message, nonce, theirPublicKey, mySecretKey)

а также:

      nacl.box.open(box, nonce, theirPublicKey, mySecretKey)

и не

      nacl.box.open(box, nonce, myPublicKey, theirSecretKey)

где последний выглядит более логичным, и я действительно не понимаю, есть ли опечатка или я не понял, как ее использовать.

в любом случае, насколько я понимаю, NaCl использует Ed25519 только для подписи, но X25519 (где Curve25519 бирационально равен Ed25519) для шифрования Pubkey, поэтому я создал тест:

      // get seed from mnemonic ising bip39 library
let targetKeyPair = web3.Keypair.fromSeed(Uint8Array.from(seed.slice(0,32)))

// derive nacl.box.Keypair from secret
let targetNaclKeyPair = nacl.box.keyPair.fromSecretKey(targetKeyPair.secretKey.slice(0,32))

// convert Ed25519 to X25519 using e2curve
let targetDHPublicKey = ed2curve.convertPublicKey(targetKeyPair.publicKey.toBytes())
let targetDHSecretKey = ed2curve.convertSecretKey(targetKeyPair.secretKey.slice(0,32))


// do similar stuff for master key
let masterKeyPair = web3.Keypair.fromSecretKey(secretKey)
let masterNaclKeyPair = nacl.box.keyPair.fromSecretKey(secretKey.slice(0,32))
let masterDHPublicKey = ed2curve.convertSecretKey(masterKeyPair.publicKey.toBytes())
var masterDHSecretKey = ed2curve.convertSecretKey(masterKeyPair.secretKey.slice(0,32))

// prepare nonce and message
let nonce = Uint8Array.from(entropy, x => x.charCodeAt(0)).slice(0,24)
let msg = Uint8Array.from("some super secret message!!!", x => x.charCodeAt(0))

console.log('toEncrypt', msg)

// wrap call to nacl for future testing
function encryptData(toEncrypt, nonce, pk, sk) {
    return nacl.box(toEncrypt, nonce, pk, sk)
}

function decryptData(toDecrypt, nonce, pk, sk) {
    return nacl.box.open(toDecrypt, nonce, pk, sk)
}

// create encrypted message from Target to Master and back with all keypair sets
let encryptedMessageFromMasterToTarget = encryptData(msg, nonce, targetKeyPair.publicKey.toBytes(), masterKeyPair.secretKey.slice(0,32))
let encryptedMessageFromTargetToMaster = encryptData(msg, nonce, masterKeyPair.publicKey.toBytes(), targetKeyPair.secretKey.slice(0,32))
let encryptedMessageFromNaclMasterToTarget = encryptData(msg, nonce, targetNaclKeyPair.publicKey, masterNaclKeyPair.secretKey)
let encryptedMessageFromNaclTargetToMaster = encryptData(msg, nonce, masterNaclKeyPair.publicKey, targetNaclKeyPair.secretKey)
let encryptedMessageFromDHMasterToTarget = encryptData(msg, nonce, targetDHPublicKey, masterDHSecretKey)
let encrypredMessageFromDHTargetToMaster = encryptData(msg, nonce, masterDHPublicKey, targetDHSecretKey)

console.log('encrypted message from master to target: ', encryptedMessageFromMasterToTarget)
console.log('encrypted message from target to master: ', encryptedMessageFromTargetToMaster)
console.log('encryptedMessageFromNaclMasterToTarget', encryptedMessageFromNaclMasterToTarget)
console.log('encryptedMessageFromNaclTargetToMaster', encryptedMessageFromNaclTargetToMaster)
console.log('encryptedMessageFromDHMasterToTarget', encryptedMessageFromDHMasterToTarget)
console.log('encrypredMessageFromDHTargetToMaster', encrypredMessageFromDHTargetToMaster)


// decrypt message with argument order from tweetnacl documentation
let decryptedMessageFromMasterToTarget = decryptData(encryptedMessageFromMasterToTarget, nonce, targetKeyPair.publicKey.toBytes(), masterKeyPair.secretKey.slice(0,32))
let decryptedMessageFromTargetToMaster = decryptData(encryptedMessageFromTargetToMaster, nonce, masterKeyPair.publicKey.toBytes(), targetKeyPair.secretKey.slice(0,32))
let decryptedMessageFromNaclMasterToTarget = decryptData(encryptedMessageFromNaclMasterToTarget, nonce, targetNaclKeyPair.publicKey, masterNaclKeyPair.secretKey)
let decryptedMessageFromNaclTargetToMaster = decryptData(encryptedMessageFromNaclTargetToMaster, nonce, masterNaclKeyPair.publicKey, targetNaclKeyPair.secretKey)
let decryptedMessageFromDHMasterToTarget = decryptData(encryptedMessageFromDHMasterToTarget, nonce, targetDHPublicKey, masterDHSecretKey)
let decryptedMessageFromDHTargetToMaster = decryptData(encrypredMessageFromDHTargetToMaster, nonce, masterDHPublicKey, targetDHSecretKey)

// decrypt message with argument order from tweetnacl documentation
let decryptedReverseMessageFromMasterToTarget = decryptData(encryptedMessageFromMasterToTarget, nonce, masterKeyPair.publicKey.toBytes(), targetKeyPair.secretKey.slice(0,32))
let decryptedReverseMessageFromTargetToMaster = decryptData(encryptedMessageFromTargetToMaster, nonce, targetKeyPair.publicKey.toBytes(), masterKeyPair.secretKey.slice(0,32))
let decryptedReverseMessageFromNaclMasterToTarget = decryptData(encryptedMessageFromNaclMasterToTarget, nonce, masterNaclKeyPair.publicKey, targetNaclKeyPair.secretKey)
let decryptedReverseMessageFromNaclTargetToMaster = decryptData(encryptedMessageFromNaclTargetToMaster, nonce, targetNaclKeyPair.publicKey, masterNaclKeyPair.secretKey)
let decryptedReverseMessageFromDHMasterToTarget = decryptData(encryptedMessageFromDHMasterToTarget, nonce, masterDHPublicKey, targetDHSecretKey)
let decryptedReverseMessageFromDHTargetToMaster = decryptData(encrypredMessageFromDHTargetToMaster, nonce, targetDHPublicKey, masterDHSecretKey)

console.log('decrypted message from master to target: ', decryptedMessageFromMasterToTarget)
console.log('decrypted message from target to master: ', decryptedMessageFromTargetToMaster)
console.log('decryptedMessageFromNaclMasterToTarget', decryptedMessageFromNaclMasterToTarget)
console.log('decryptedMessageFromNaclTargetToMaster', decryptedMessageFromNaclTargetToMaster)
console.log('decryptedMessageFromDHMasterToTarget', decryptedMessageFromDHMasterToTarget)
console.log('decryptedMessageFromDHTargetToMaster', decryptedMessageFromDHTargetToMaster)

console.log('decryptedReverseMessageFromMasterToTarget', decryptedReverseMessageFromMasterToTarget)
console.log('decryptedReverseMessageFromTargetToMaster', decryptedReverseMessageFromTargetToMaster)
console.log('decryptedReverseMessageFromNaclMasterToTarget', decryptedReverseMessageFromNaclMasterToTarget)
console.log('decryptedReverseMessageFromNaclTargetToMaster', decryptedReverseMessageFromNaclTargetToMaster)
console.log('decryptedReverseMessageFromDHMasterToTarget', decryptedReverseMessageFromDHMasterToTarget)
console.log('decryptedReverseMessageFromDHTargetToMaster', decryptedReverseMessageFromDHTargetToMaster)

после запуска теста я получил очень интересные результаты:

      toEncrypt Uint8Array(28) [
  115, 111, 109, 101,  32, 115, 117,
  112, 101, 114,  32, 115, 101,  99,
  114, 101, 116,  32, 109, 101, 115,
  115,  97, 103, 101,  33,  33,  33
]
encrypted message from master to target:  Uint8Array(44) [
  122,  99, 177, 120,  62, 111, 165, 208,  58,
  204, 206, 199, 163, 253, 204,  67, 223, 171,
   76,  83, 158, 156, 107, 240, 106, 230,  75,
  169,   9,  16,  72, 164, 104, 236,  99,  77,
  224,  27, 225,  17, 161, 156, 105, 187
]
encrypted message from target to master:  Uint8Array(44) [
  132, 248,   6,  59, 219,  67, 101,  81, 221,
  134, 117, 200, 163, 105,  55,  67,   2, 148,
  206, 231,  46, 146, 198, 168, 248, 241,  82,
   16, 244,  53,  98,  27, 189,  91, 241,  63,
  145, 119,  27,  81,  65, 158, 250, 216
]
encryptedMessageFromNaclMasterToTarget Uint8Array(44) [
  118, 213,  85, 253, 123, 205,   4, 179,  93,
   40,  80, 155, 136, 180, 150, 163, 208, 155,
  253,  93, 104,  93, 101, 249,  60, 233,  29,
  186, 222, 152, 239,  32,  18, 253,  11,  71,
  165,  39, 204,  83,  78, 223, 220, 246
]
encryptedMessageFromNaclTargetToMaster Uint8Array(44) [
  118, 213,  85, 253, 123, 205,   4, 179,  93,
   40,  80, 155, 136, 180, 150, 163, 208, 155,
  253,  93, 104,  93, 101, 249,  60, 233,  29,
  186, 222, 152, 239,  32,  18, 253,  11,  71,
  165,  39, 204,  83,  78, 223, 220, 246
]
encryptedMessageFromDHMasterToTarget Uint8Array(44) [
   26,  22,   0, 190,  81, 129, 130, 122, 205,
   78, 116,  19,  15, 181, 182, 228,  74, 154,
    5,  75, 191,  97, 217, 140, 155, 124,  12,
  108,  36,   0,  66,  60, 250, 184, 251, 183,
   56,   0,  26, 220, 152,  91, 236,  98
]
encrypredMessageFromDHTargetToMaster Uint8Array(44) [
  78, 219,  56,  57, 177, 158, 255,  43, 112,
  81, 251,  44, 119,  46, 179, 233,  83,  71,
  69, 131, 136, 242,  63,  46, 120, 128, 123,
   0,  78, 128,  79,   1,  96,  40,  25,  31,
  47, 193, 204, 203, 151, 246, 113,  79
]
decrypted message from master to target:  Uint8Array(28) [
  115, 111, 109, 101,  32, 115, 117,
  112, 101, 114,  32, 115, 101,  99,
  114, 101, 116,  32, 109, 101, 115,
  115,  97, 103, 101,  33,  33,  33
]
decrypted message from target to master:  Uint8Array(28) [
  115, 111, 109, 101,  32, 115, 117,
  112, 101, 114,  32, 115, 101,  99,
  114, 101, 116,  32, 109, 101, 115,
  115,  97, 103, 101,  33,  33,  33
]
decryptedMessageFromNaclMasterToTarget Uint8Array(28) [
  115, 111, 109, 101,  32, 115, 117,
  112, 101, 114,  32, 115, 101,  99,
  114, 101, 116,  32, 109, 101, 115,
  115,  97, 103, 101,  33,  33,  33
]
decryptedMessageFromNaclTargetToMaster Uint8Array(28) [
  115, 111, 109, 101,  32, 115, 117,
  112, 101, 114,  32, 115, 101,  99,
  114, 101, 116,  32, 109, 101, 115,
  115,  97, 103, 101,  33,  33,  33
]
decryptedMessageFromDHMasterToTarget Uint8Array(28) [
  115, 111, 109, 101,  32, 115, 117,
  112, 101, 114,  32, 115, 101,  99,
  114, 101, 116,  32, 109, 101, 115,
  115,  97, 103, 101,  33,  33,  33
]
decryptedMessageFromDHTargetToMaster Uint8Array(28) [
  115, 111, 109, 101,  32, 115, 117,
  112, 101, 114,  32, 115, 101,  99,
  114, 101, 116,  32, 109, 101, 115,
  115,  97, 103, 101,  33,  33,  33
]
decryptedReverseMessageFromMasterToTarget null
decryptedReverseMessageFromTargetToMaster null
decryptedReverseMessageFromNaclMasterToTarget Uint8Array(28) [
  115, 111, 109, 101,  32, 115, 117,
  112, 101, 114,  32, 115, 101,  99,
  114, 101, 116,  32, 109, 101, 115,
  115,  97, 103, 101,  33,  33,  33
]
decryptedReverseMessageFromNaclTargetToMaster Uint8Array(28) [
  115, 111, 109, 101,  32, 115, 117,
  112, 101, 114,  32, 115, 101,  99,
  114, 101, 116,  32, 109, 101, 115,
  115,  97, 103, 101,  33,  33,  33
]
decryptedReverseMessageFromDHMasterToTarget null
decryptedReverseMessageFromDHTargetToMaster null

Когда используется производный nacl.box.keyPair, кажется, единственное рабочее решение для обратного дешифрования, однако зашифрованное сообщение абсолютно одинаково для обоих направлений (от главного к целевому и наоборот). совершенно неправильно, и преобразование в ed2curve также не работает должным образом. Даже если подумать, что все расшифрованные сообщения с не обратным порядком аргументов возвращают правильные данные!

Итак, мой вопрос: как правильно использовать пары ключей Solana для шифрования с открытым ключом (асимметричного)?

0 ответов

Другие вопросы по тегам