Node.js加解密

无论加密解密、字符转换,都需要使用byte,而node对byte的支持不如其他语言(如c/java,可以直接使用byte[])方便快捷,但是也有模块对byte提供支持。

node对byte处理的支持


Buffer

Buffer支持很多格式转换(Ascii, urf8, usc2, utf16le, base64, binary, hex),传入字符串可以直接进行格式转换:
new Buffer(size); // with size
new Buffer(array) // with array
new Buffer(str[, encoding]) // with string[, encoding = 'utf8']

Int*Array

构造函数如下(都是一样的),因此不能直接传入字符串:

Int8Array(bufferOrArrayOrLength,byteOffset,length)

使用Buffer可以直接将字符串转为HEX,使用Int8Array可以直接转换为标准byte(-128 ~ 127)数组:

// hex: 41 ~ 5A
var UPPER = new Int8Array(new Buffer('ABCDEFGHIJKLMNOPQRSTUVWXYZ'));
// hex: 61 ~ 7A
var lower = new Int8Array(new Buffer('abcdefghijklmnopqrstuvwxyz0123456789'));
// hex: 30 ~ 39
var number = new Int8Array(new Buffer('0123456789'));

如果使用Uint8Array,则转换为无符号的byte(0 ~ 255)数组:

var u = new Uint8Array(new Buffer('123456'));

使用的第三模块


forge - npm install node-forge --save

<a name="buf" />

froge Buffer

使用forge,加解密byte数据都需要使用forge.util.ByteStringBuffer
可以通过方法forge.util.createBuffer()来创建一个新的Buffer。

// put, get
util.ByteStringBuffer.prototype.putByte = function(b)
util.ByteStringBuffer.prototype.getByte = function()
...
util.ByteStringBuffer.prototype.at = function(i)

Buffer内部有两个游标,read cursor和write cursor,只用put和get均会使游标前进,使用.at(i)可以不影响游标而直接获取相应的值。

<a name="rsa" />

rsa

生成KeyPair:

var rsa = forge.pki.rsa;
// generate an RSA key pair synchronously
var keypair = rsa.generateKeyPair({bits: 2048, e: 0x10001});
// generate an RSA key pair asynchronously (uses web workers if available)
// use workers: -1 to run a fast core estimator to optimize # of workers
rsa.generateKeyPair({bits: 2048, workers: 2}, function(err, keypair) { 
// keypair.privateKey, keypair.publicKey
});

使用

// encrypt data with a public key using RSAES-OAEP/SHA-256/MGF1-SHA-1
// compatible with Java's RSA/ECB/OAEPWithSHA-256AndMGF1Padding
var encrypted = publicKey.encrypt(bytes, 'RSA-OAEP', {
  md: forge.md.sha256.create(),
  mgf1: {
    md: forge.md.sha1.create()
  }
});

// decrypt data with a private key using RSAES-OAEP/SHA-256/MGF1-SHA-1
// compatible with Java's RSA/ECB/OAEPWithSHA-256AndMGF1Padding
var decrypted = privateKey.decrypt(encrypted, 'RSA-OAEP', {
  md: forge.md.sha256.create(),
  mgf1: {
    md: forge.md.sha1.create()
  }
});

通过已经生成的key(asn1格式)来生成Key对象

// public key
var key = forge.asn1.fromDer(pubKey);
var publicKey =  forge.pki.publicKeyFromAsn1(key);
// private key
var key = forge.asn1.fromDer(priKey);
var privateKey =  forge.pki.privateKeyFromAsn1(key);

生成Key对象后解密

/**
 * @param ed the encrypted data to decrypt in as a byte string. 
 * @param key the RSA key to use.
 * @param pub true for a public key operation, false for private. 
 * @param ml the message length, if known, false to disable padding. 
 *
 * @return the decrypted message as a byte string. 
*/
pki.rsa.decrypt = function(ed, key, pub, ml) 

解密后的字符串实际上是

util.ByteStringBuffer.prototype.getBytes = function() {...}

<a name="aes" />

aes

aes通过forge.cipher.createCipher('AES-ECB', key)来创建cipher使用(JAVA中AES对应的即是AES-ECB)。

// decrypt aes, aesKey[ByteStringBuffer]
var aesCipher = forge.cipher.createDecipher('AES-ECB', aesKey);
aesCipher.start();
aesCipher.update(encryptedData);
if (!aesCipher.finish()) {  
  throw new Error('decrypt error');
}
var decryptData = aesCipher.output;

<a name="md5" />

md5

// verify md5
var md = forge.md.md5.create();
md.update(decryptData);
var mdToVerify = md.digest();

<a name="other" />

其他

forge还有其他很多模块,可以参见https://github.com/digitalbazaar/forge

推荐阅读更多精彩内容

  • /**ios常见的几种加密方法: 普通的加密方法是讲密码进行加密后保存到用户偏好设置( [NSUserDefaul...
    彬至睢阳阅读 2,322评论 0 6
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 129,292评论 18 137
  • 首先罗列一些知识点: 1.加密算法通常分为对称性加密算法和非对称性加密算法:对于对称性加密算法,信息接收双方都需事...
    JonesCxy阅读 1,049评论 2 4
  • https://nodejs.org/api/documentation.html 工具模块 Assert 测试 ...
    KeKeMars阅读 5,722评论 0 6
  • 若我躺在凉水般月光中 若你听得见我心中忧愁 若微风吹起 若梧桐作响 你会思念我否?
    相思隔山溪不绝阅读 91评论 0 0
  • 我欲效古风 仗剑踏歌行 镪镪刀入骨 烈烈马嘶鸣 长空烟蔽日 阵前鼓槌隆 血气弥肆野 花叶断春风
    啸傲天涯_阿思蓝阅读 573评论 2 2
  • 好多父母都受不了孩子哭。 孩子不哭的时候和孩子玩的超级开心欢笑不断,孩子一哭,立马心烦意乱百爪挠心,孩子哭起来没完...
    若宁说阅读 404评论 1 4
  • 怎样做到真正的严格? 我常常想起读书时候的一位老教授。每次提到他,大家都说他的学生质量很高。我一直很好奇他是怎样做...
    心如莲花2006阅读 285评论 0 0
  • 23岁的时候,你妈问你:“怎么还没有男朋友?” 你说工作刚开始,要稳定;你说学习重要,先考研;你说交际圈太小,没有...
    吾聊职场阅读 478评论 1 1