Skip to content
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

decrypt encrypted text with php? #18

Open
pixelpaulaus opened this issue May 31, 2021 · 1 comment
Open

decrypt encrypted text with php? #18

pixelpaulaus opened this issue May 31, 2021 · 1 comment

Comments

@pixelpaulaus
Copy link

Has anyone used PHP to decrypt the encrypted text with this package?
I am wanting to make something in PHP that can decrypt and use something from my database which was encrypted with this package. But not sure where and how to get started.

@sehrope
Copy link
Owner

sehrope commented May 31, 2021

The encryption is done with standard AES-256 in CBC mode. Any language with OpenSSL bindings should be able to decrypt it. I'm not particularly familiar with PHP but looks like it'd be openssl_decrypt(...): https://www.php.net/manual/en/function.openssl-decrypt.php

The key used to perform the AES operation is the SHA-256 of the text key option:

var cryptoKey = crypto.createHash('sha256').update(key).digest();

The output format is documented here:

// Encrypts an arbitrary object using the derived cryptoKey and retursn the result as text.
// The object is first serialized to JSON (via JSON.stringify) and the result is encrypted.
//
// The format of the output is:
// [<hmac>]<iv><encryptedJson>
//
// <hmac> : Optional HMAC
// <iv> : Randomly generated initailization vector
// <encryptedJson> : The encrypted object
function encrypt(obj) {
var json = JSON.stringify(obj);
// First generate a random IV.
// AES-256 IV size is sixteen bytes:
var iv = crypto.randomBytes(16);
// Make sure to use the 'iv' variant when creating the cipher object:
var cipher = crypto.createCipheriv('aes-256-cbc', cryptoKey, iv);
// Generate the encrypted json:
var encryptedJson = cipher.update(json, 'utf8', 'base64') + cipher.final('base64');
// Include the hex-encoded IV + the encrypted base64 data
// NOTE: We're using hex for encoding the IV to ensure that it's of constant length.
var result = iv.toString('hex') + encryptedJson;
if( verifyHmac ) {
// Prepend an HMAC to the result to verify it's integrity prior to decrypting.
// NOTE: We're using hex for encoding the hmac to ensure that it's of constant length
result = hmac(result, 'hex') + result;
}
return result;
}

You'd need to split out the pieces, convert them hex to bytes, and then you should be able to invoke the corresponding OpenSSL functions to decrypt it. The JS code for this library is purposely verbose and should match up with the same steps in other languages:

function decrypt(cipherText) {
if( !cipherText ) {
return null;
}
try {
if( verifyHmac ) {
// Extract the HMAC from the start of the message:
var expectedHmac = cipherText.substring(0, 64);
// The remaining message is the IV + encrypted message:
cipherText = cipherText.substring(64);
// Calculate the actual HMAC of the message:
var actualHmac = hmac(cipherText);
if( !scmp(Buffer.from(actualHmac, 'hex'), Buffer.from(expectedHmac, 'hex')) ) {
throw new Error('HMAC does not match');
}
}
// Extract the IV from the beginning of the message:
var iv = Buffer.from(cipherText.substring(0,32), 'hex');
// The remaining text is the encrypted JSON:
var encryptedJson = cipherText.substring(32);
// Make sure to use the 'iv' variant when creating the decipher object:
var decipher = crypto.createDecipheriv('aes-256-cbc', cryptoKey, iv);
// Decrypt the JSON:
var json = decipher.update(encryptedJson, 'base64', 'utf8') + decipher.final('utf8');
// Return the parsed object:
return JSON.parse(json, reviver);
} catch( e ) {
// If we get an error log it and ignore it. Decrypting should never fail.
if( debug ) {
console.error('Exception in decrypt (ignored): %s', e);
}
return null;
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants