admin管理员组文章数量:1313733
Hi im trying to read my greenpass certificate, and i know that when you scan the QR code it will appear something like this HC1:NHFDFGDF......, i also know this is encoded as base45 so i made a little javascript decoder, this is my code:
const base45 = require('base45');
//of course my personal HC1: isnt here
const encodedData = 'C0C9BQF2LVU.TMBX4KDL*XD/GPWBILC9GGBYPLR-SAG1CSQ6U7SSQY%SJWLK34JWLG56H0API0TUL:12>'
const decodedData = base45.decode(encodedData).toString('utf-8');
console.log(decodedData);
And this is the response:
xڻ�⻈Q��C#?��-E�����K�BX���ֳI%|�zl�ȼ�qIbY㪤��
�Ң<�Ҳ�L�� ?��0gO+C��+�`��`׀0�H'W�P���WweϤ�|��I)yLI)%YFF��f�FfI�ť��y��%�We�+�$*'ޕ�������kh�f��I�9�����F����F�I�)LI%�&�ƖfIeY��������)�IY���F {
�sVp����*8���z�8*��:;'������
pMN�+*��*�+JN�+�� �
��**K-J5�3�3�p8���yM]�o����E�_��O.�ϩ����
�g�˽��\�����="��]۷
����������{��Kq ��
what i read is that its decoding of base45 will lead to zlib pressed file, where the depression will lead a CBOR web token, but im stuck, can you help me ? Is this result normal ? also im still learning
Hi im trying to read my greenpass certificate, and i know that when you scan the QR code it will appear something like this HC1:NHFDFGDF......, i also know this is encoded as base45 so i made a little javascript decoder, this is my code:
const base45 = require('base45');
//of course my personal HC1: isnt here
const encodedData = 'C0C9BQF2LVU.TMBX4KDL*XD/GPWBILC9GGBYPLR-SAG1CSQ6U7SSQY%SJWLK34JWLG56H0API0TUL:12>'
const decodedData = base45.decode(encodedData).toString('utf-8');
console.log(decodedData);
And this is the response:
xڻ�⻈Q��C#?��-E�����K�BX���ֳI%|�zl�ȼ�qIbY㪤��
�Ң<�Ҳ�L�� ?��0gO+C��+�`��`׀0�H'W�P���WweϤ�|��I)yLI)%YFF��f�FfI�ť��y��%�We�+�$*'ޕ�������kh�f��I�9�����F����F�I�)LI%�&�ƖfIeY��������)�IY���F {
�sVp����*8���z�8*��:;'������
pMN�+*��*�+JN�+�� �
��**K-J5�3�3�p8���yM]�o����E�_��O.�ϩ����
�g�˽��\�����="��]۷
����������{��Kq ��
what i read is that its decoding of base45 will lead to zlib pressed file, where the depression will lead a CBOR web token, but im stuck, can you help me ? Is this result normal ? also im still learning
Share Improve this question edited Aug 1, 2021 at 17:41 Sven Eberth 3,11612 gold badges25 silver badges31 bronze badges asked Aug 1, 2021 at 17:21 Sh4dowSh4dow 311 gold badge1 silver badge4 bronze badges 7- That is not valid Base45 input. Please recheck that you have correctly copied and pasted it into the code. Your decoding does in fact start with two bytes indicating a zlib header. However you should never post binary data in printed form, since it cannot be read. All those white-on-black question marks are parts of the binary that could not be printed, and so are lost and pletely useless to someone trying to help you. Always put binary data in a question as hexadecimal or Base-64. – Mark Adler Commented Aug 1, 2021 at 23:49
- this is part of the string that follows HC1:, when we scan the QR code: NCFOXN%TSMAHN-H.L8%38Q%T6$823S0IIYMJ the one that i read that is encoded as base45, here is where i've seen it, but i wanna make it a little different: dev.to/lmillucci/…, and i changed the utf-8 to hex, this was what i got, its just a part of it, not all: 78dabbd4e2bb88518dc543233ff5ec2d45cfde05918c9a4b1893024258a4128ff2d6b349257ca87a6cc9c8bc9071496259e3aaa4e4cc0ac3d2a23cabd2b2e44 – Sh4dow Commented Aug 2, 2021 at 0:57
- In the question. Put the Base64 in the question. Not in these ments. (As you noticed, ments are length limited. And they are not where information needed to answer the question belong. That place is called the question.) And please delete the attempted printout of the binary in the question. – Mark Adler Commented Aug 2, 2021 at 1:17
- That is a valid zlib stream. So yes, your result normal and correct. – Mark Adler Commented Aug 2, 2021 at 1:19
- thanks, in the web site i showed he was using pako to unpress it, but is giving me an error, is it possible to use zlib to unpress it ? – Sh4dow Commented Aug 2, 2021 at 1:32
2 Answers
Reset to default 5I solved the problem using only browser resources (no node.js); I also found some official sources for explanations, test data, field decoding (see at the end of the answer):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="generator" content="PSPad editor, www.pspad.">
<title></title>
</head>
<body>
<textarea id="encoded" name="encoded" cols=100 rows=10></textarea><br>
<textarea id="decoded" name="decoded" cols=100 rows=10 value = "prova">hello</textarea><br>
<span id="plain1" name="plain1">-</span> -->
<span id ="cod" name="cod">-</span> -->
<span id="plain2" name="plain2">-</span><br>
<button onclick="test()">Test</button><br>
<button onclick="vai()">Vai</button><br>
<script src="pako.min.js"></script>
<script src="my_base45_2.js"></script>
<script src="cbor.js" type="text/javascript"></script>
<script>
// https://dev.to/lmillucci/javascript-how-to-decode-the-greenpass-qr-code-3dh0
function convert(decoded) {
text="";
for (var i = 0; i < decoded.length; i++) {
text += String.fromCharCode(decoded[i]);
}
console.log("Text=",text);
values = text.split(",");
console.log("values: " ,values);
final = "";
for (var i=0; i<values.length; i++) {
final += String.fromCharCode(values[i])
}
return final;
}
function test() {
source = document.getElementById("decoded").value;
console.log("source=",source);
document.getElementById("plain1").innerHTML = source;
var enc = new TextEncoder();
buff= enc.encode(source);
console.log("buff:" , buff);
encoded2 = encode(buff);
console.log("encoded2:" , encoded2);
document.getElementById("cod").innerHTML = encoded2;
source = encoded2;
console.log("Encoded source=",source);
decoded = decode(source).enc;
converted = convert(decoded);
console.log("Decoded=", decoded);
console.log("converted=", converted);
document.getElementById("plain2").innerHTML = converted;
}
function buf2hex(buffer) {
// https://stackoverflow./questions/34309988/byte-array-to-hex-string-conversion-in-javascript
var u = new Uint8Array(buffer),
a = new Array(u.length),
i = u.length;
while (i--) // map to hex
a[i] = (u[i] < 16 ? '0' : '') + u[i].toString(16);
u = null; // free memory
return a.join('');
};
function typedArrayToBuffer(array) {
// https://stackoverflow./questions/37228285/uint8array-to-arraybuffer
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
}
function vai() {
source = document.getElementById("encoded").value;
console.log("Encoded source=",source);
// Decode BASE45:
decoded = decode(source).enc;
// Unzip the decoded:
COSEbin = pako.inflate(decode(source).raw);
COSE = buf2hex(COSEbin);
var typedArray = new Uint8Array(COSE.match(/[\da-f]{2}/gi).map(function (h) {
return parseInt(h, 16)
})) // https://stackoverflow./questions/43131242/how-to-convert-a-hexadecimal-string-of-data-to-an-arraybuffer-in-javascript
var unzipped = typedArray.buffer;
[headers1, headers2, cbor_data, signature] = CBOR.decode(unzipped);
cbor_dataArr = typedArrayToBuffer(cbor_data);
greenpassData = CBOR.decode(cbor_dataArr);
console.log(greenpassData);
}
</script>
</body>
</html>
The key is the "double CBOR decoding": once is not enough:
CBOR decoding:
[headers1, headers2, cbor_data, signature] = CBOR.decode(unzipped);
Conversion to Array:
cbor_dataArr = typedArrayToBuffer(cbor_data);
Further CBOR conversion:
greenpassData = CBOR.decode(cbor_dataArr);
My version of base45 decoder ("my_base45_2.js"), adapted from a node.js version:
function encode(uint8array) {
var output = [];
for (var i = 0, length = uint8array.length; i < length; i+=2) {
if (uint8array.length -i > 1) {
var x = (uint8array[i]<<8)+ uint8array[i+1]
var [ e, x ] = divmod(x, 45*45)
var [ d, c ] = divmod(x, 45)
output.push(fromCharCode(c) + fromCharCode(d) + fromCharCode(e))
} else {
var x = uint8array[i]
var [ d, c ] = divmod(x, 45)
output.push(fromCharCode(c) + fromCharCode(d))
}
}
return output.join('')
};
var divmod = function divmod(a,b) {
var remainder = a
var quotient = 0
if (a >= b) {
remainder = a % b
quotient = (a - remainder) / b
}
return [ quotient, remainder ]
}
const BASE45_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"
var fromCharCode = function fromCharCode(c) {
return BASE45_CHARSET.charAt(c);
};
function decode(str) {
var output = []
var buf = []
for(var i = 0, length=str.length; i < length; i++) {
//console.log(i);
var j = BASE45_CHARSET.indexOf(str[i])
if (j < 0)
console.log('Base45 decode: unknown character n.', i, j);
//throw new Error('Base45 decode: unknown character');
buf.push(j)
}
for(var i = 0, length=buf.length; i < length; i+=3) {
var x = buf[i] + buf[i + 1] * 45
if (length - i >= 3) {
var [d, c] = divmod(x + buf[i + 2] * 45 * 45,256)
output.push(d)
output.push(c)
} else {
output.push(x)
}
}
console.log("output",output);
var enc = new TextEncoder();
return {"enc" : enc.encode(output), "raw" : output};
//return Buffer.from(output);
};
These are the decoding steps:
QR code --> QR DECODER --> RAW QR-decoded string --> BASE45 decoder --> zlib pressed string --> pako library --> COSE string --> CBOR decoder --> CBOR string --> CBOR decoder --> final JSON file
- Original base45 node.js decoder: https://github./dirkx/base45-js/blob/main/lib/base45-js.js
- Zlib unpacker library for browser: https://github./nodeca/pako/blob/master/dist/pako.min.js
- CBOR unpacker: https://github./paroga/cbor-js
- Dummy greenpass for testing: https://gir.st/blog/img/greenpass-demo.png
- Official data for testing: https://github./eu-digital-green-certificates/dgc-testdata/tree/main/IT/png
- Documentation on json fields: https://ec.europa.eu/health/sites/default/files/ehealth/docs/digital-green-certificates_dt-specifications_en.pdf
- Databases for decoding fields values: https://github./ehn-dcc-development/ehn-dcc-schema/tree/release/1.3.0/valuesets
My reference guides for decoding greenpass:
https://dev.to/lmillucci/javascript-how-to-decode-the-greenpass-qr-code-3dh0
https://gir.st/blog/greenpass.html
Sample data containing 5 strings:
- Original QR-decoded string
- BASE45 string
- Compressed string
- COSE string
- CBOR string
const base45 = require('base45');
const encodedData = 'NCFOXN%TSMAHN-H.L8%38Q%T6$823S0IIYMJ 43%C0C9BQF2LVU.TMBX4KDL*XD/GPWBILC9GGBYPLR-SAG1CSQ6U7SSQY%SJWLK34JWLG56H0API0TUL:12'
const decodedData = base45.decode(encodedData).toString('hex');
console.log(decodedData);
Result:
78dabbd4e2bb88518dc543233ff5ec2d45cfde05918c9a4b1893024258a4128ff2d6b349257ca87a6cc9c8bc9071496259e3aaa4e4cc0ac3d2a23cabd2b2e44cabd0203fabd030674f2b0343ab80102bdf60aba060d78030e34813275713f750b7d0c8c808577765cfa4e47ca0894929794c4929255946064686ba0666ba46664999c5a5be997999c52587571665e62ba4242a04271ede95929a949b98eb1fe4ae6b6800048666969649b90539aea1fa86fa4686fa86a6469649c5294c4925e999162606a6c6960606664965055986868696c606a60606a6c929f949598696a646207b0ccd92f312739724a5e515b8b82a38faf8ba7aba382af8843a3b0627a5e7e5f8841eee0d5670f3f4f10c704d4ecb2b012ab2812ab2012b4a4ecf2bc9f609f50cb6812a2a4b2d4a35d433d033887038a4b4a4794d5dc66f8fcdf9b545815fb9a64f2ebfcfa9f9f2f7c71b458d67a6cbbdb38d0f5cf1f1c7d9e7013d22d1de1c5ddbb70ac9fd88b9cff2ecdf14c6e77bbe854b0100710988a7
本文标签: javascriptDecode a base45 string that will lead to a cbor compressed fileStack Overflow
版权声明:本文标题:javascript - Decode a base45 string that will lead to a cbor compressed file - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741958427a2407124.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论