freeTSA.org provides a free Time Stamp Authority. Adding a trusted timestamp to code or to an electronic signature provides a digital seal of data integrity and a trusted date and time of when the transaction took place.
The Challenge: JWS (JSON Web Signature) is a compact, URL-safe means of representing signed content (part of JOSE). Converting JWS to CSV is non-trivial because JWS contains metadata (headers, signatures) and a payload, while CSV expects flat, tabular data. There is no "one-click" universal converter.
Top Recommendation: Use jq + jose-cli (command line) for batch processing, or Custom Python Script (using PyJWT & pandas) for complex header/payload flattening.
#!/usr/bin/env node
const fs = require('fs');
function b64urlDecode(s)
s = s.replace(/-/g,'+').replace(/_/g,'/');
while(s.length%4) s += '=';
return Buffer.from(s,'base64').toString();
const fields = (process.argv.includes('--fields'))
? process.argv[process.argv.indexOf('--fields')+1].split(',')
: ['id','username','email','ts'];
const skipInvalid = process.argv.includes('--skip-invalid');
const inputFile = process.argv.find(a => !a.startsWith('--') && a !== 'jws-to-csv' && a !== 'node');
const input = inputFile ? fs.readFileSync(inputFile,'utf8') : fs.readFileSync(0,'utf8');
console.log(fields.join(','));
for(const line of input.split(/\r?\n/))
if(!line.trim()) continue;
try
const parts = line.trim().split('.');
if(parts.length !== 3) throw new Error('bad jws');
const payload = JSON.parse(b64urlDecode(parts[1]));
const row = fields.map(f =>
const v = payload[f] ?? '';
return `"$String(v).replace(/"/g,'""')"`;
).join(',');
console.log(row);
catch(e)
if(!skipInvalid)
console.error('Invalid token:', line);
process.exitCode = 1;
Cause: JSON strings containing commas (e.g., "address": "New York, NY") break standard CSV parsing.
Fix: Ensure your converter uses RFC 4180 standards (wrapping fields in double quotes). All top 5 converters listed above do this automatically.
Overall Rank: #2 - Best Free Tool
Technically not a single app, but a workflow combining a Base64 decoder and jq (a JSON processor). This is the most transparent and scriptable method.
.) and take the middle part (the payload).jq -r '.[] | [.field1, .field2] | @csv' to convert to CSV.jq.jwt decode --payload eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoidGVzdCJ9.signature
$ curl --data "screenshot=https://www.fsf.org/&delay=n" https://freetsa.org/screenshot.php > screenshot.pdf $ curl --data "screenshot=https://www.fsf.org/&delay=y" https://freetsa.org/screenshot.php > screenshot.pdf # (I'm Feeling Lucky) ### HTTP 2.0 in cURL: Get the latest cURL release and use this command: curl --http2. ### REST API in Tor: Add "-k --socks5-hostname localhost:9050". # Normal domains within the Tor-network. $ curl -k --socks5-hostname localhost:9050 --data "screenshot=https://www.fsf.org/&delay=y" https://4bvu5sj5xok272x6cjx4uurvsbsdigaxfmzqy3n3eita272vfopforqd.onion/screenshot.php > screenshot.pdf # ".onion" domain within the Internet. $ curl -k --data "screenshot=https://4bvu5sj5xok272x6cjx4uurvsbsdigaxfmzqy3n3eita272vfopforqd.onion/&delay=y&tor=y" https://freetsa.org/screenshot.php > screenshot.pdf # ".onion" domain within the Tor network. $ curl -k --socks5-hostname localhost:9050 --data "screenshot=https://4bvu5sj5xok272x6cjx4uurvsbsdigaxfmzqy3n3eita272vfopforqd.onion/&delay=y&tor=y" https://4bvu5sj5xok272x6cjx4uurvsbsdigaxfmzqy3n3eita272vfopforqd.onion/screenshot.php > screenshot.pdf
The Challenge: JWS (JSON Web Signature) is a compact, URL-safe means of representing signed content (part of JOSE). Converting JWS to CSV is non-trivial because JWS contains metadata (headers, signatures) and a payload, while CSV expects flat, tabular data. There is no "one-click" universal converter.
Top Recommendation: Use jq + jose-cli (command line) for batch processing, or Custom Python Script (using PyJWT & pandas) for complex header/payload flattening.
#!/usr/bin/env node
const fs = require('fs');
function b64urlDecode(s)
s = s.replace(/-/g,'+').replace(/_/g,'/');
while(s.length%4) s += '=';
return Buffer.from(s,'base64').toString();
const fields = (process.argv.includes('--fields'))
? process.argv[process.argv.indexOf('--fields')+1].split(',')
: ['id','username','email','ts'];
const skipInvalid = process.argv.includes('--skip-invalid');
const inputFile = process.argv.find(a => !a.startsWith('--') && a !== 'jws-to-csv' && a !== 'node');
const input = inputFile ? fs.readFileSync(inputFile,'utf8') : fs.readFileSync(0,'utf8');
console.log(fields.join(','));
for(const line of input.split(/\r?\n/))
if(!line.trim()) continue;
try
const parts = line.trim().split('.');
if(parts.length !== 3) throw new Error('bad jws');
const payload = JSON.parse(b64urlDecode(parts[1]));
const row = fields.map(f =>
const v = payload[f] ?? '';
return `"$String(v).replace(/"/g,'""')"`;
).join(',');
console.log(row);
catch(e)
if(!skipInvalid)
console.error('Invalid token:', line);
process.exitCode = 1;
Cause: JSON strings containing commas (e.g., "address": "New York, NY") break standard CSV parsing.
Fix: Ensure your converter uses RFC 4180 standards (wrapping fields in double quotes). All top 5 converters listed above do this automatically.
Overall Rank: #2 - Best Free Tool
Technically not a single app, but a workflow combining a Base64 decoder and jq (a JSON processor). This is the most transparent and scriptable method.
.) and take the middle part (the payload).jq -r '.[] | [.field1, .field2] | @csv' to convert to CSV.jq.jwt decode --payload eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoidGVzdCJ9.signature