Skip to content

Instantly share code, notes, and snippets.

@Roman2K
Created September 29, 2012 18:22
Show Gist options
  • Save Roman2K/3804792 to your computer and use it in GitHub Desktop.
Save Roman2K/3804792 to your computer and use it in GitHub Desktop.
Ruby/node encryption/decryption
const crypto = require('crypto');
const PASSWORD = "098f6bcd4621d373cade4e832627b4f6"
, MESSAGE = 'test';
function InvalidSignatureError() {
Error.captureStackTrace(this, this.constructor);
}
function encipher(message, password, callback) {
crypto.randomBytes(16, function(err, iv) {
if (err) return callback(err);
var cipher = crypto.createCipheriv('aes-256-cbc', password, iv)
, enciphered = '';
enciphered += cipher.update(message, 'utf-8', 'binary');
enciphered += cipher.final('binary');
enciphered = new Buffer(enciphered, 'binary');
var encipheredMessage = [enciphered.toString('base64'), iv.toString('base64')].join('--');
callback(null, encipheredMessage);
});
}
function decipher(encipheredMessage, password, callback) {
var parts = encipheredMessage.split('--', 2)
, enciphered = new Buffer(parts[0], 'base64')
, iv = new Buffer(parts[1], 'base64');
var decipher = crypto.createDecipheriv('aes-256-cbc', password, iv)
, deciphered = '';
deciphered += decipher.update(enciphered);
deciphered += decipher.final();
callback(null, deciphered);
}
function sign(message, password, callback) {
var signer = crypto.createHmac('sha256', password);
signer.update(message);
var signature = signer.digest('binary');
message = new Buffer(message, 'utf-8');
signature = new Buffer(signature, 'binary');
var signedMessage = [message.toString('base64'), signature.toString('base64')].join('--');
callback(null, signedMessage);
}
function verify(signedMessage, password, callback) {
var parts = signedMessage.split('--', 2)
, encodedMessage = new Buffer(parts[0], 'base64')
, signature = new Buffer(parts[0], 'base64')
, message = encodedMessage.toString('utf-8');
sign(message, password, function(err, signedMessageForVerification) {
if (signedMessage != signedMessageForVerification)
return callback(new InvalidSignatureError());
callback(null, message);
});
}
console.log('MESSAGE =', MESSAGE);
encipher(MESSAGE, PASSWORD, function(err, encipheredMessage) {
if (err) throw err;
console.log('encipheredMessage =', encipheredMessage);
sign(encipheredMessage, PASSWORD, function(err, signedMessage) {
if (err) throw err;
console.log('signedMessage =', signedMessage);
verify(signedMessage, PASSWORD, function(err, verifiedMessage) {
if (err) throw err;
console.log('verifiedMessage =', verifiedMessage);
decipher(verifiedMessage, PASSWORD, function(err, deciphered) {
if (err) throw err;
console.log('deciphered =', deciphered);
});
});
});
});
require 'openssl'
class InvalidSignatureError < StandardError
end
PASSWORD = "098f6bcd4621d373cade4e832627b4f6"
MESSAGE = "test"
def encipher(message, password)
cipher = OpenSSL::Cipher::AES256.new(:CBC)
iv = cipher.random_iv
cipher.encrypt
cipher.key = PASSWORD
cipher.iv = iv
enciphered = cipher.update(MESSAGE)
enciphered << cipher.final
[enciphered, iv].map { |part| [part].pack('m').gsub(/\n/, '') }.join('--')
end
def decipher(enciphered_message, password)
enciphered, iv = enciphered_message.split('--', 2).map { |part| part.unpack('m')[0] }
decipher = OpenSSL::Cipher::AES256.new(:CBC)
decipher.decrypt
decipher.key = PASSWORD
decipher.iv = iv
deciphered = decipher.update(enciphered)
deciphered << decipher.final
end
def sign(message, password)
signature = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, password, message)
[message, signature].map { |part| [part].pack('m').gsub(/\n/, '') }.join('--')
end
def verify(signed_message, password)
encoded_message, signature = signed_message.split('--', 2)
message = encoded_message.unpack('m')[0]
if sign(message, password) != signed_message
raise InvalidSignatureError
end
message
end
puts "MESSAGE = #{MESSAGE}"
enciphered_message = encipher(MESSAGE, PASSWORD)
puts "enciphered_message = #{enciphered_message}"
signed_message = sign(enciphered_message, PASSWORD)
puts "signed_message = #{signed_message}"
verified_message = verify(signed_message, PASSWORD)
puts "verified_message = #{verified_message}"
deciphered = decipher(verified_message, PASSWORD)
puts "deciphered = #{deciphered}"
@ajaymehra05
Copy link

Hey Roman,

I have a code in node.js which i am writing it on ruby but got stuck in the Buffer(str, encoding) function which i am not able to find out in ruby.Here is js code(It uses crypto library) which i want it in ruby :
I testsed with ID =2 and APPID=1

function generateProfileId(ID, applicationId) {
// add zero padding for at the beginning of the number pick lowest 6 bytes
var hexMemberId = ('0000000000000000' + ID.toString(16)).substr(-12);
console.log(hexMemberId); //000000000002
// put APPID into two highest bytes of ID id
var hexAppId = APPID.toString(16);
console.log(hexAppId);//1
var hexMidAppId = ('0000' + hexAppId + hexMemberId).substr(-16);//<Buffer 00 01 00 00 00 00 00 02>
console.log(hexMidAppId);//0001000000000002
var midBuffer = new Buffer(hexMidAppId, 'hex');
console.log(midBuffer); //< Buffer 00 01 00 00 00 00 00 02 >
var key = 'PLACEHOLDER';
var hmacBuffer = createHMACDigest(key, midBuffer);
console.log(hmacBuffer); //01c690ac02eb572fde4a096a076aaa8501ea3671bf
var outputBuffer = Buffer.concat([midBuffer, new Buffer(hmacBuffer, 'hex')]);
console.log(outputBuffer); //<Buffer 00 01 00 00 00 00 00 02 01 c6 90 ac 02 eb 57 2f de 4a 09 6a 07 6a aa 85 01 ea 36 71 bf>
console.log(outputBuffer.toString('base64')); //AAEAAAAAAAIBxpCsAutXL95KCWoHaqqFAeo2cb8=
return outputBuffer.toString('base64');
}
function createHMACDigest(key, paddedMemberId) {
return '01' + Crypto.createHmac('sha1', key).update(paddedMemberId).digest('hex');
}

Any help would be highly appreciated

Here is the step log for the js codes:
000000000002
1
0001000000000002
< Buffer 00 01 00 00 00 00 00 02 >
01c690ac02eb572fde4a096a076aaa8501ea3671bf
<Buffer 00 01 00 00 00 00 00 02 01 c6 90 ac 02 eb 57 2f de 4a 09 6a 07 6a aa 85 01 ea 36 71 bf>
AAEAAAAAAAIBxpCsAutXL95KCWoHaqqFAeo2cb8=

@prcongithub
Copy link

I had to replace + with space in the verify methods for url encoded messages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment