Алгоритм шифрования:
Как шифровать?
Шифрование работает в 3 этапа. Первоначально выберите алгоритм шифрования на основе алгоритма, создайте случайный ключ необходимой длины в соответствии с требованиями алгоритма, а также создайте iv (вектор инициализации) из 16 байтов независимо от алгоритма шифрования.
Затем зашифруйте ключ, используя сертификат клиента.< br /> Наконец, зашифруйте данные с помощью зашифрованного ключа и iv.
Ниже добавлены утилиты шифрования с использованием библиотеки шифрования и подделки.
IV и ключ
let iv = crypto.randomBytes(8).toString('hex'); let IVECTOR = Buffer.from(iv); let randomKey = crypto.randomBytes(16).toString('hex'); let publiccert = fs.readFileSync(keyPath);
Шифрование ключей:
/** * publicCert - client public certificate - string format * input - string 32 bytes */ const encryptKey = (input, publicCert) => { // console.log(publicCert.toString()); const cert = forge.pki.certificateFromPem(publicCert); let publicKey = forge.pki.publicKeyToPem(cert.publicKey); return RSA_ECB_PKCS1Padding(input, publicKey); } const RSA_ECB_PKCS1Padding = (input, publicKey) => { let publicKeyz = forge.pki.publicKeyFromPem(publicKey); // convert string to UTF-8 encoded bytes let buffer = forge.util.createBuffer(input, 'utf8'); let bytes = buffer.getBytes(); // encrypt data with a public key using RSAES PKCS#1 v1.5 let encrypted = publicKeyz.encrypt(bytes, 'RSAES-PKCS1-V1_5'); // base64-encode encrypted data to send to server return forge.util.encode64(encrypted); }
Шифрование данных:
/** * data - should be in string format * IVECTOR should be in buffer format - size 16 bytes * key should be in string format */ const encryptAESCBCPKCS7Padding = (data, key, IVECTOR) => { // console.log("encryption data", data, key, IVECTOR); const cipher = crypto.createCipheriv('aes-256-cbc', key, IVECTOR); cipher.setAutoPadding(true); const dataBuffer = Buffer.from(data, 'utf8'); const ivAndData = Buffer.concat([IVECTOR, dataBuffer]); //const encryptedValue = cipher.update(ivAndData); //if iv is required const encryptedValue = cipher.update(dataBuffer); //if iv is not required const finalEncryptedValue = Buffer.concat([encryptedValue, cipher.final()]); return finalEncryptedValue.toString('base64'); }
Алгоритм расшифровки
Требуется — закрытый ключ, зашифрованный ключ и зашифрованные данные.
Используйте закрытый ключ для расшифровки ключа, который в дальнейшем будет использоваться при расшифровке данных.
Используйте зашифрованные данные, чтобы найти iv (если iv отдельно не дается) и расшифрованный ключ для поиска исходных данных.
Алгоритм расшифровки:
let key = fs.readFileSync(keypath); let originalsymmetrickey = RSA_ECB_PKCS1Padding_Decrypt(encryptedresponse.data.encryptedKey, key); console.log(originalsymmetrickeyj); originalEncryptedData = DecryptDataWithoutIv(encryptedData, originalsymmetrickey); console.log(originalEncryptedData);
Расшифровка ключа RSA:
/** * input - string * private key - string */ const RSA_ECB_PKCS1Padding_Decrypt = function (input, privateKey) { input = forge.util.decode64(input); //console.log(input.length); var privateKey = forge.pki.privateKeyFromPem(privateKey); var decrypted = privateKey.decrypt(input, 'RSAES-PKCS1-V1_5'); return decrypted; }
Расшифровка данных:
/** * encryptedData - String * originalsymmetrickey - 16 bytes as used aes-128-cbc */ const DecryptDataWithoutIv = (encryptedData, originalsymmetrickey) => { let bufferObj = Buffer.from(encryptedData, "base64"); let iv = bufferObj.subarray(0, 16); //get iv from encrypted data return decryptAESCBCPKCS7Padding(bufferObj, originalsymmetrickey, iv); } const decryptAESCBCPKCS7Padding = (encryptedDataBuffer, key, IVECTOR) => { const decipher = crypto.createDecipheriv('aes-128-cbc', key, IVECTOR); decipher.setAutoPadding(true); const decryptedValue = decipher.update(encryptedDataBuffer); const finalDecryptedValue = Buffer.concat([decryptedValue, decipher.final()]); // Extract the IVECTOR and the decrypted data from the final value const decryptedData = finalDecryptedValue.subarray(IVECTOR.length); return decryptedData.toString('utf8'); }