Last active
April 29, 2022 18:11
-
-
Save johnatandias/d8b6fa5805fb44f09c94b87e5b8c7d40 to your computer and use it in GitHub Desktop.
Web Crypto API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<title></title> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<script> | |
const encodeData = () => { | |
const longJson = JSON.stringify([{ | |
"id": "0001", | |
"type": "donut", | |
"name": "Cake", | |
"ppu": 0.55, | |
"batters": { | |
"batter": [{ | |
"id": "1001", | |
"type": "Regular" | |
}, { | |
"id": "1002", | |
"type": "Chocolate" | |
}, { | |
"id": "1003", | |
"type": "Blueberry" | |
}, { | |
"id": "1004", | |
"type": "Devil's Food" | |
}] | |
}, | |
"topping": [{ | |
"id": "5001", | |
"type": "None" | |
}, { | |
"id": "5002", | |
"type": "Glazed" | |
}, { | |
"id": "5005", | |
"type": "Sugar" | |
}, { | |
"id": "5007", | |
"type": "Powdered Sugar" | |
}, { | |
"id": "5006", | |
"type": "Chocolate with Sprinkles" | |
}, { | |
"id": "5003", | |
"type": "Chocolate" | |
}, { | |
"id": "5004", | |
"type": "Maple" | |
}] | |
}, { | |
"id": "0002", | |
"type": "donut", | |
"name": "Raised", | |
"ppu": 0.55, | |
"batters": { | |
"batter": [{ | |
"id": "1001", | |
"type": "Regular" | |
}] | |
}, | |
"topping": [{ | |
"id": "5001", | |
"type": "None" | |
}, { | |
"id": "5002", | |
"type": "Glazed" | |
}, { | |
"id": "5005", | |
"type": "Sugar" | |
}, { | |
"id": "5003", | |
"type": "Chocolate" | |
}, { | |
"id": "5004", | |
"type": "Maple" | |
}] | |
}, { | |
"id": "0003", | |
"type": "donut", | |
"name": "Old Fashioned", | |
"ppu": 0.55, | |
"batters": { | |
"batter": [{ | |
"id": "1001", | |
"type": "Regular" | |
}, { | |
"id": "1002", | |
"type": "Chocolate" | |
}] | |
}, | |
"topping": [{ | |
"id": "5001", | |
"type": "None" | |
}, { | |
"id": "5002", | |
"type": "Glazed" | |
}, { | |
"id": "5003", | |
"type": "Chocolate" | |
}, { | |
"id": "5004", | |
"type": "Maple" | |
}] | |
}]) | |
const shortJson = JSON.stringify({ | |
descricao: 'DORIME', | |
status: 'ATIVO', | |
}) | |
const textEncoder = new TextEncoder() | |
const encodedData = textEncoder.encode(JSON.stringify(longJson)) | |
return { | |
encodedData | |
} | |
} | |
const counter = window.crypto.getRandomValues(new Uint8Array(16)) | |
const generateAesKey = async() => { | |
const aesCryptoKey = await window.crypto.subtle.generateKey({ | |
name: "AES-CTR", | |
length: 256 | |
}, | |
true, ["encrypt", "decrypt"] | |
) | |
const exportedAesCryptoKey = await window.crypto.subtle.exportKey( | |
"raw", | |
aesCryptoKey | |
); | |
const exportedAesKeyBuffer = new Uint8Array(exportedAesCryptoKey); | |
console.log({ | |
exportedAesKeyBuffer | |
}) | |
return { | |
aesCryptoKey, | |
rawAesKey: exportedAesKeyBuffer | |
} | |
} | |
const aesEncrypt = async(aesCryptoKey, encodedData) => { | |
const aesEncryptedData = await window.crypto.subtle.encrypt({ | |
name: "AES-CTR", | |
counter, | |
length: 64 | |
}, | |
aesCryptoKey, | |
encodedData | |
); | |
return { | |
aesEncryptedData | |
} | |
} | |
const rsaEncryptAesKey = async(aesKey) => { | |
// const jwk = { | |
// kty: 'RSA', | |
// e: 'AQAB', | |
// use: 'enc', | |
// kid: 'NSBIXzSuhCzev1VCQ2_bY1BDcnuYTWf4pw9Mz4ZvQGw', | |
// alg: 'RSA-OAEP-512', | |
// n: 'lotRefvlFPDHnBrWeArh3AHdrP9UXZ0t1mD7eykE1RoaSGN78dwSEPdPyRVFmk2HGqCIH4kA-mT-KjT4rOr0JZxCoUHcDU_yeYOyFIORXeSv8RKEfYcC6Ifo9HyBtDO4eyUfIu3sTyeD4GO2xYxu-ZzT3_8guctIELXf-8e40WNuztGSmDbvlEu6i7HjT661ubEsfV3JWRqvIzpkgImcMPh7POcEi-PJgiu4cXktO2TLIpg1dnCnIhIlQWOcrSz3wMIsD8tkvqJk1SRuHoyp_V8arfg-ocTt4IpNAmyMmboqwatIQTe7OpN4Pku1sHjH1PFOi9Ta-kQlFBrW_EwQVQ', | |
// } | |
// const rsaCryptoKey = await window.crypto.subtle.importKey( | |
// 'jwk', | |
// jwk, { | |
// name: 'RSA-OAEP', | |
// hash: { | |
// name: 'SHA-512' | |
// }, | |
// label: new Uint8Array([1, 0, 1]), | |
// }, | |
// false, ['encrypt'], | |
// ) | |
const newKeyPair = await window.crypto.subtle.generateKey({ | |
name: "RSA-OAEP", | |
modulusLength: 4096, | |
publicExponent: new Uint8Array([0x01, 0x00, 0x01]), | |
hash: { | |
name: "SHA-256" | |
}, | |
}, | |
false, ["encrypt", "decrypt"] | |
) | |
const { | |
privateKey, | |
publicKey: rsaCryptoKey | |
} = newKeyPair | |
const rsaEncryptedData = await window.crypto.subtle.encrypt({ | |
name: 'RSA-OAEP', | |
}, | |
rsaCryptoKey, | |
aesKey, | |
) | |
return { | |
aesKeyEncryptedInRsa: rsaEncryptedData, | |
rsaPrivateKey: privateKey, | |
} | |
} | |
const encryptMessage = async() => { | |
const { | |
encodedData | |
} = encodeData() | |
const { | |
aesCryptoKey, | |
rawAesKey | |
} = await generateAesKey() | |
const { | |
aesEncryptedData | |
} = await aesEncrypt(aesCryptoKey, encodedData) | |
const { | |
aesKeyEncryptedInRsa, | |
rsaPrivateKey, | |
} = await rsaEncryptAesKey(rawAesKey) | |
return { | |
aesEncryptedData, | |
aesKeyEncryptedInRsa, | |
rsaPrivateKey, | |
} | |
} | |
(async() => { | |
const { | |
aesEncryptedData, | |
aesKeyEncryptedInRsa, | |
rsaPrivateKey | |
} = await encryptMessage() | |
console.log({ | |
aesEncryptedData, | |
aesKeyEncryptedInRsa, | |
rsaPrivateKey | |
}) | |
// Test only | |
const decryptMessage = async(aesEncryptedKeyInRsa, privateRsaKey, aesEncryptedData) => { | |
const aesKey = await window.crypto.subtle.decrypt({ | |
name: 'RSA-OAEP', | |
}, | |
privateRsaKey, | |
aesEncryptedKeyInRsa, | |
) | |
console.log({ | |
aesKey | |
}) | |
const aesKeyFinal = await window.crypto.subtle.importKey( | |
"raw", | |
aesKey, { | |
name: "AES-CTR", | |
counter, | |
length: 64 | |
}, | |
false, ['decrypt'] | |
); | |
const data = await window.crypto.subtle.decrypt({ | |
name: "AES-CTR", | |
counter, | |
length: 64 | |
}, | |
aesKeyFinal, | |
aesEncryptedData | |
); | |
const textDecoder = new TextDecoder() | |
const decrytedData = JSON.parse(textDecoder.decode(data)) | |
console.log({ | |
decrytedData | |
}) | |
} | |
await decryptMessage(aesKeyEncryptedInRsa, rsaPrivateKey, aesEncryptedData) | |
})() | |
</script> | |
</head> | |
<body> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment