Как сгенерировать и проверить JWE в узле js?

Я попробовал приведенный ниже код для создания генератора и валидатора JWE RSA-OAEP и A128GCM. он работает с узлом js, т. е. шифрует утверждения и генерирует jwe и расшифровывает то же самое, что дает мне утверждения. но он не работает с другими клиентами, такими как nimbusds jose, jose4j. Так что я точно что-то упускаю.

Я делаю это, читая https://tools.ietf.org/html/rfc7516

index.js

var crypto = require('crypto');
var randomstring = require("randomstring");
var ursa = require("ursa");
var fs = require("fs");
var base64url = require('base64url');
var ascii = require("./ASCII");


var claims = {
    firstName: "vimal"
};

var header = {
    "enc": "A128GCM",
    "alg": "RSA-OAEP"
};

var headerBase64Url = base64url.encode(JSON.stringify(header));
console.log("headerBase64Url : " + headerBase64Url);
console.log("headerBase64Url to UTF8 : " + base64url.decode(headerBase64Url));


var cek = randomstring.generate(16);
console.log("cek : " + cek);

var publicKey = ursa.createPublicKey(fs.readFileSync('./pubkey.pem'));
var encryptedKey = publicKey.encrypt(cek, 'utf8', 'base64');
console.log("encryptedKey : " + encryptedKey);

// var privateKey = ursa.createPrivateKey(fs.readFileSync('./privkey.pkc8.pem'));
// var decryptedKey = privateKey.decrypt(encryptedKey, "hex", "utf8");

// console.log("decryptedKey : " + decryptedKey);


var iv = randomstring.generate(12);
console.log("IV : " + iv);
var cipher = crypto.createCipheriv('aes-128-gcm', cek, iv);
cipher.setAAD(Buffer.from(ascii.toASCII(headerBase64Url)));
var chipherText = cipher.update(JSON.stringify(claims), "utf8", "base64");
chipherText += cipher.final('base64');
console.log("chipherText : " + chipherText);
var chipherTextAuthTag = cipher.getAuthTag().toString("base64");
console.log("chipherText Auth Tag : " + chipherTextAuthTag);


var jweToken = headerBase64Url + "." + base64url.encode(encryptedKey, "base64") + "." + base64url.encode(iv, "base64") + "." + base64url.encode(chipherText, "base64") +
    "." + base64url.encode(chipherTextAuthTag, "base64");
console.log("jweToken : " + jweToken);


// decrypt

var jweTokenParts = jweToken.split(".");

var headerHex = base64url.decode(jweTokenParts[0]);
console.log(headerHex);
var encryptedKeyHex = base64url.decode(jweTokenParts[1], "base64");
console.log(encryptedKeyHex);
var ivHex = base64url.decode(jweTokenParts[2], "base64");
console.log(ivHex);
var chipperTextHex = base64url.decode(jweTokenParts[3], "base64");
console.log(chipperTextHex);
var chipherTextAuthTagHex = base64url.decode(jweTokenParts[4], "base64");
console.log(chipherTextAuthTagHex);


var privateKey = ursa.createPrivateKey(fs.readFileSync('./privkey.pkc8.pem'));
var decryptedKeyHex = privateKey.decrypt(encryptedKeyHex, "base64", "utf8");

console.log("decryptedKeyHex : " + decryptedKeyHex);

var dcipher = crypto.createDecipheriv('aes-128-gcm', decryptedKeyHex, iv);
dcipher.setAAD(Buffer.from(ascii.toASCII(jweTokenParts[0])));
dcipher.setAuthTag(Buffer.from(chipherTextAuthTagHex, "base64"));
var planText = dcipher.update(chipperTextHex, "base64", "utf8");
planText += dcipher.final('utf8');
console.log(planText);

ASCII.js

function toASCII(text) {
    var ascii = "";
    for (var f in text) {
        ascii = ascii + text.charCodeAt(f);
    }

    return ascii;
}

module.exports = {
    toASCII: toASCII
};

Сгенерирован открытый и закрытый ключ с помощью следующей команды

openssl genrsa -out ./privkey.pem 2048

openssl pkcs8 -topk8 -inform pem -in ./privkey.pem -outform pem -nocrypt -out ./privkey.pkc8.pem

openssl rsa -in ./privkey.pkc8.pem -pubout -out ./pubkey.pem

Пожалуйста, помогите мне исправить этот код.

Это мой открытый ключ

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyT0HZHrlk8nN8HfTDq5t
dv6UCKHf7+RF1bICxaR4h2vzGCqcYUlzyW7Sp33BZAHDeO3d5tX26m7z2EOPaOPn
SSe6psgvBmE4Ivyc3+uyIYJm+Eo9bXiqqfvuDRidXsHj23w41l6GMERKbpOBVvp+
dmWt/cWU8FESvKUqNw/Au2R9mE1sQ5irMQj42hhUrVA1azs2AYpysKNZABm11YMb
/vd/xSPLsNqcDefuCs7j3CcT9xNLrMV6K63QjCAP+h0IMuA+ayi3WRUbl04D6cAC
AC97/cKMC0YLRumbf5x5/KjUBwNlzgRA3/n9KE+YjJ9Rs9dtiGnlg+c70Kgx4hm9
9QIDAQAB
-----END PUBLIC KEY-----

Сгенерированный JWE

eyJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ.A_KMJqfr6FZSoejRGWPsZKMCNZmPyaWoNvpG6KMRpqyv7Alb8Ui5ELWLjpcaemjNM8EFU8d4-Yzz8jRRZ5TpK2pEEc4NXfDLcnj2b0-38_-P-0HbW1YyMkkGMVXIpJDYMo8vKgVHIBj0pNlzgF7xmxLFWZlJlXmYzXi4QZcig5HezHg7AAQB7U2HYry25cQDYam60747gRCH372NaSm_dfRCNvH8copVXqiJGNs6xhslxMt_LopnZt9iIcAC9o7m0FPdnu_0Ui_w0jp5OUam8i0v8k6SSajBvXSedtUENxcehPGRSFYzi8KqZ53u4CpRygir84wNFRTi7zmLV6TlVw.84xgyx6TTI8I.4zTt1fI1XCbvxW2L-pH8_Mfp_ySF.EPmpEHiMYAvA2nqz9M0v5Q

person vimal prakash    schedule 08.12.2017    source источник
comment
Не могли бы вы поделиться с нами открытым ключом и примером JWE?   -  person Spomky-Labs    schedule 10.12.2017
comment
@FlorentMorselli Я редактировал вопрос с открытым ключом и токеном   -  person vimal prakash    schedule 11.12.2017
comment
Спасибо. Жетон правильно подделан. Я вижу две возможности: либо CEK не зашифрован правильно, либо декодер не работает должным образом. Чтобы проверить первое предположение, мне нужен закрытый ключ. Для второго вы можете попробовать загрузить токен, созданный другим приложением (я могу отправить вам его в приватном чате, если хотите)   -  person Spomky-Labs    schedule 11.12.2017
comment
@FlorentMorselli Да, пожалуйста, мой электронный адрес: [email protected]   -  person vimal prakash    schedule 12.12.2017


Ответы (1)


Похоже, что IV неправильно закодирован с использованием URL-адреса Base64. На моем компьютере, когда я выполняю следующую строку кода:

console.log(iv);
console.log(base64url.encode(iv, "base64"));

Тогда две строки идентичны. Когда я изменяю ваш код:

var jweToken = headerBase64Url + "." + base64url.encode(encryptedKey, "base64") + "." + base64url.encode(iv, "base64") + "." + base64url.encode(chipherText, "base64") +
"." + base64url.encode(chipherTextAuthTag, "base64");

В эти строки:

var bufferedIV = new Buffer(iv);
var jweToken = headerBase64Url + "." + base64url.encode(encryptedKey, "base64") + "." + base64url.encode(bufferedIV, "base64") + "." + base64url.encode(chipherText, "base64") +
"." + base64url.encode(chipherTextAuthTag, "base64");

Тогда все работает нормально; Я могу загрузить полученный JWE, используя свою библиотеку PHP.

Насколько я понимаю, ошибка возникает из-за зависимости base64url, которая неправильно кодирует IV.

person Spomky-Labs    schedule 21.12.2017
comment
привет @Florent, не могли бы вы поделиться со мной библиотекой php. Я пробовал использовать свой Java-код, и он не работает. :( - person vimal prakash; 05.01.2018