js 加密解密

MD5 (Message-Digest Algorithm) 信息摘要算法

  • 罗纳德·李维斯特(Ron Rivest)开发出的一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value)length为32的String,用于确保信息传输完整一致。
  • 该算法于1992年发布,但是在2004年,证实MD5算法无法防止碰撞(collision),因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。
  • js中的应用
npm install md5
import md5 from 'md5'
md5(message) // message: String, Buffer, Array or Uint8Array

Hmac

  • Hmac算法也是一种哈希算法,它可以利用MD5或SHA1等哈希算法。不同的是,Hmac还需要一个密钥
// node.js 的crypto模块
const crypto = require('crypto');
const hmac = crypto.createHmac('sha256', 'secret-key');
hmac.update('Hello, world!');
hmac.update('Hello, nodejs!');
console.log(hmac.digest('hex')); // 80f7e22570...

Diffie-Hellman

// node的crypto模块
DH算法是一种密钥交换协议,它可以让双方在不泄漏密钥的情况下协商出一个密钥来。
示例见https://www.liaoxuefeng.com/wiki/1022910821149312/1023025778520640

RSA算法

  • RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。
  • 是一个典型的**非对称加密**,公开密钥体制,使用不同的加密密钥与解密密钥,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的,加密算法和解密算法也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。
  • 安全性:RSA允许你选择公钥的大小。512位的密钥被视为不安全的;768位的密钥不用担心受到除了美国国家安全局(NSA)外的其他事物的危害;1024位的密钥几乎是安全的。
  • 通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,信息采用改进的DES或IDEA对话密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要
  • 公钥、私钥有何特点?
    公钥加密的,私钥可以解密;
    私钥加密的,公钥可以解密。
    但公钥加密的,公钥无法解密;
    私钥加密的,私钥也无法解密!
  • js 中应用
以下网址可以生成pem标准格式的秘钥字符串
`http://web.chacuo.net/netrsakeypair`
// 公钥
let pk = `-----BEGIN PUBLIC KEY-----
          MIGfMA......Qm
          -----END PUBLIC KEY-----`
  // 私钥
let sk = `-----BEGIN PRIVATE KEY-----
           MIICeA......gJeAgEAAoGBAP        
          -----END PRIVATE KEY-----`;
  // 原文
let msg = "好厉害";
// 使用jsencrypt
npm install jsencrypt
import JsEncrypt from 'jsencrypt'
// 获取加密 jsencrypt 
const encryptBody = function(data) {
  let encode = new JsEncrypt();
  // 写入公钥
  encode.setPublicKey(pk);
  // 返回加密数据
  return encode.encrypt(data);
};

//解密
const decryptBody = function(data) {
  let decode = new JSEncrypt();
  // 写入私钥
  decode.setPrivateKey(sk)
  // 返回解密数据
  return decode.decrypt(data);
};
// request body msg
encryptBody(msg)
// response body msg
decryptBody(msg)
// 使用jsrsasign
npm install jsrsasign
import rs from 'jsrsasign'
// 加密
let prvKey = rs.KEYUTIL.getKey(pk);
let enc = rs.KJUR.crypto.Cipher.encrypt(msg, prvKey);
console.log(enc,rs.hextob64(enc));
// 解密
let prv = rs.KEYUTIL.getKey(sk);
// get enc from fava
let dec = rs.KJUR.crypto.Cipher.decrypt(enc, prv);
console.log("jsrsasign decrypt: " + dec);
// 签名
    var key = rs.KEYUTIL.getKey(sk);
    let signature=new rs.KJUR.crypto.Signature({alg:"SHA1withRSA"});
    signature.init(key);
    signature.updateString(msg);
    let a = signature.sign();
    let sign = rs.hextob64(a);
    console.log(sign);
// 验签
    let signatureVf = new 
    rs.KJUR.crypto.Signature({alg:"SHA1withRSA",prvkeypem:pk});
    signatureVf.updateString(msg);
    // get sign from java
    let boolean = signatureVf.verify(rs.b64tohex(sign));
    console.log("jsrsasign verify: "+boolean);

AES (Advanced Encryption Standard)高级加密标准

  • 2001年发布,是**对称密钥加密**体系
  • 这个标准用来替代原先的DES(Data Encryption Standard)
  • JS中的应用
import CryptoJS from 'crypto-js'
// 加密
export const encrypt = (word, keyStr) => {
  keyStr = keyStr || '16进制的字符串'
  var key = CryptoJS.enc.Utf8.parse(keyStr)
  var srcs = CryptoJS.enc.Utf8.parse(word)
  var iv = CryptoJS.enc.Utf8.parse('ABCDEF1234123412');
  var encrypted = CryptoJS.AES.encrypt(srcs, key, {
    iv: iv,
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
  })
  return encrypted.toString()
}
// 解密
export const decrypt = (word, keyStr) => {
  keyStr = keyStr || '16进制的字符串'
  // 如果后端给的是WordBuffer类型的数据,将Utf8换成hex
  // 如果后端进行base64编码
  // CryptoJS.enc.Base64.stringify(encryptedHexStr);
  var key = CryptoJS.enc.Utf8.parse(keyStr)
  var iv = CryptoJS.enc.Utf8.parse('ABCDEF1234123412');
  var decrypt = CryptoJS.AES.decrypt(word, key, {
    iv: iv,
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
  })
  return CryptoJS.enc.Utf8.stringify(decrypt).toString()
}

DES (Data Encryption Standard)即数据加密标准

import CryptoJS from 'crypto-js'
//DES加密
function encryptByDES(message, key){
    var keyHex = CryptoJS.enc.Utf8.parse(key);
    var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });
    return encrypted.ciphertext.toString();
}
//DES解密
function decryptByDES(ciphertext, key){
    var keyHex = CryptoJS.enc.Utf8.parse(key);
    var decrypted = CryptoJS.DES.decrypt({
        ciphertext: CryptoJS.enc.Hex.parse(ciphertext)
    }, keyHex, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });
    var result_value = decrypted.toString(CryptoJS.enc.Utf8);
    return result_value;
}

3DES (Triple Data Encryption Algorithm)三重数据加密算法

  • 也叫Triple DES,1981年发布,是DES向AES过渡的加密算法
  • 由于计算机运算能力的增强,DES密码的密钥长度变得容易被暴力破解,3DES就是通过增加DES的密钥长度来避免类似的攻击
  • js中的应用
import CryptoJS from 'crypto-js'
//秘钥key
var key = "12345677654321";
//key不足24位自动以0(最小位数是0)补齐,如果多余24位,则截取前24位,后面多余则舍弃掉
var base64 = CryptoJS.enc.Utf8.parse(key)
//加密使用的是3DES中的ECB,解密对应的使用ECB
function encrypt() {
  var text = document.getElementById("content").innerText;
  var encrypt = CryptoJS.TripleDES.encrypt(text, base64, {
    iv: CryptoJS.enc.Utf8.parse('01234567'),//iv偏移量
    // mode: CryptoJS.mode.CBC,  //CBC模式
    mode: CryptoJS.mode.ECB,  //ECB模式
    padding: CryptoJS.pad.Pkcs7//padding处理
  });
  return encrypt.toString()
}
//解密
function decrypt() {
  var text = document.getElementById("encrypt").innerText;
  var decrypt = CryptoJS.TripleDES.decrypt(text, base64, {
    iv: CryptoJS.enc.Utf8.parse('01234567'),
    // mode: CryptoJS.mode.CBC,
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
  });
  return decrypt.toString(CryptoJS.enc.Utf8)
}

SHA-2/3安全散列算法2/3

SHA-1不够安全,不能继续使用,是SHA-1的后继者

国密SM2/4

数字签名过程

其实就是浏览器的网页与服务器之间的认证过程
其中使用了rsa加密算法
a、b都有公钥,z有私钥,az为朋友,b为诈骗中间人

  1. a给z发一封信件,a使用公钥加密后发给z,z使用私钥解密
    z给a回信,决定使用数字签名
  2. z写完回信后先用Hash函数,生成信件的摘要(digest),然后,使用私钥,对这个摘要加密,生成"数字签名"(signature),然后将回信和签名发送给a
  3. a收信后,取下数字签名,用z的公钥解密,得到信件的摘要。由此证明,这封信确实是z发出的。
  4. a再对信件本身使用Hash函数,将得到的摘要结果,与上一步得到的摘要进行对比。如果两者一致,就证明这封信未被修改过。
  5. 复杂情况来了,b用a的电脑时将a的公钥换成了b的公钥,a和b就可以如上述流程就行通信了,b以此来冒充z,与a进行通信
  6. 后来,a感觉不对劲,发现自己无法确定公钥是否真的属于z。她想到了一个办法,要求z去找"证书中心"(certificate authority,简称CA),为公钥做认证。证书中心用自己的私钥,对鲍勃的公钥和一些相关信息一起加密,生成"数字证书"(Digital Certificate)。
  7. z拿到数字证书以后,就可以放心了。以后再给a写信,只要在签名的同时,再附上数字证书就行了。
  8. a收信后,用CA的公钥(浏览器中预置了ca)解开数字证书,就可以拿到z真实的公钥了,然后就能证明"数字签名"是否真的是z签的
    此过程参考https://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_signature.html
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352