Created
September 29, 2012 18:22
-
-
Save Roman2K/3804792 to your computer and use it in GitHub Desktop.
Ruby/node encryption/decryption
This file contains hidden or 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
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); | |
}); | |
}); | |
}); | |
}); |
This file contains hidden or 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
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}" |
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
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=