-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Interoperability with javax.crypto #63
Comments
Here's a working version using standard node webcrypto import { Buffer as IsomorphicBuffer } from 'buffer/'
const { subtle } = globalThis.crypto
class Buffer extends IsomorphicBuffer {}
const base64Decode = (base64String: string): Uint8Array => {
return Uint8Array.from(Buffer.from(base64String, 'base64'))
}
const byteArrayToString = (byteArray: Uint8Array): string => {
return Buffer.from(byteArray).toString('utf8')
}
const decryptWithPreshared = async (encodedKey: string, encryptedEncodedData: string ): Promise<string> => {
const encryptedData = base64Decode(encryptedEncodedData)
const key = base64Decode(encodedKey)
const iv = encryptedData.subarray(0, 12)
const dataToDecrypt = encryptedData.subarray(12)
const cryptoKey = await subtle.importKey('raw', key, "AES-GCM", false, ['decrypt'])
const cipher: ArrayBuffer = await subtle.decrypt({ name: "AES-GCM", iv }, cryptoKey, dataToDecrypt)
return byteArrayToString(new Uint8Array(cipher))
}
decryptWithPreshared('U5yzshQRpa1aplMWK/QvbUXlHQyyVk+Zwxz8fyLKRLQ=', '0L5oGCBu1Jbe/TTcMu+4wVbK32vRK7UptQjC1zedbpL6Zq3j')
.then((txt) => {
console.log(`Decrypted string: ${txt}`)
}) |
Hey @grant-arqit ! I checked the case, and there may be a mismatch in types or behavior in k6 vs. nodejs. I need to check deeply what exactly, but currently, it's that in the k6, you have to:
🤔 For instance, below, I did some minimal working version using the data that you've provided: import { crypto } from "k6/experimental/webcrypto";
import encoding from 'k6/encoding';
const displayArrayBufferContent = (buffer) => {
return [...new Uint8Array(buffer)]
.map((x) => x.toString(10))
.join(" ");
}
function arrayBufferToString(buffer) {
return String.fromCharCode.apply(null, new Uint8Array(buffer));
}
const base64Decode = (base64String) => {
return new Uint8Array(encoding.b64decode(base64String));
}
export default async function() {
const keyData = base64Decode('U5yzshQRpa1aplMWK/QvbUXlHQyyVk+Zwxz8fyLKRLQ=');
const key = await crypto.subtle.importKey('raw', keyData, "AES-GCM", false, ['decrypt']);
const encryptedData = base64Decode('0L5oGCBu1Jbe/TTcMu+4wVbK32vRK7UptQjC1zedbpL6Zq3j');
const iv = new Uint8Array(encryptedData.subarray(0, 12));
const ciphertext = new Uint8Array(encryptedData.subarray(12));
console.log('iv: ' + displayArrayBufferContent(iv));
console.log('ciphertext: ' + displayArrayBufferContent(ciphertext));
const plaintext = await crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: iv,
},
key,
ciphertext,
);
console.log("Decrypted string: '" + arrayBufferToString(plaintext) + "'")
} that will result me with:
Let me know if that helps |
I think we also should update the k6's webcrypto docs to showcase such import 🤔 |
Thanks @olegbespalov , that's really useful feedback. I'll see if I can adapt our encoding libraries to use k6 encoding and see what further progress can be made. |
HI @olegbespalov. I have made some progress, however I am hitting on some k6 specific encoding issues by the looks of things. Do you know how url encoding is treated? One of my strings which includes
|
Hey @grant-arqit ! Glad to hear that Our encoding module is a wrapper around Golang's encoding. You have some control over which encoding is used. See the documentation at https://grafana.com/docs/k6/latest/javascript-api/k6-encoding/b64decode/ or the Golang documentation at https://pkg.go.dev/encoding/base64#pkg-variables. So I might think that you should use something like I'm not sure about RFC3986. Since it's about Uniform Resource Identifier (URI). Golang, base64 implementation is based on https://www.rfc-editor.org/rfc/rfc4648.html. |
I've managed to resolve my crypto / encoding issues now. Thanks very much your help. |
I have a service which encrypts data in a kotlin appliction with the following function.
The console output of the above standalone code is an encrypted, base64 encoded string. One example of the encrypted string is
0L5oGCBu1Jbe/TTcMu+4wVbK32vRK7UptQjC1zedbpL6Zq3j
(each execution will always be different because of the iv prefix element based on a random value)I've fed the encoded/encrypted string into the K6 test below and I get an OperationError when calling crypto.subtle.decrypt (the import function is fine).
Are you able advise what may be going wrong here and if there are any workarounds for a K6 test? Are there any known interoperability issues either between
javax.crypto
libraries and k6 webcrypto? The buffer npm libs used in the decode and byteArray to string routines successfully execute in the test, but could the conversion / decoded output be incompatible when supplying the output of these functions as inputs to k6 webcrypto? Incidently when decrypting this in a nodejs runtime environment with theisomorphic-webcrypto
implementation, decryption works fine without error.The text was updated successfully, but these errors were encountered: