crypto 先後端加解密簡單瞭解

文章記錄crypto庫的簡單瞭解和用法。javascript

  1. crypto
  2. Hash(散列)算法
  3. Hmac算法
  4. PBKDF2函數
  5. 對稱加密
  6. 小結

文中主要介紹node 的cypto模塊,結合前端crypto-js演示(crypto-js是javascript 實現的cypto庫)。html

1. crypto

Crypto++ 庫是一個用c++ 編寫的密碼類庫,提供完整的加密實現,而且一般包括不太流行,不常使用的方案。(簡單說:crypto 是一個包括了加解密算法的庫)前端

node crypto 模塊提供了加密功能,包括對 OpenSSL 的哈希、HMAC、加密、解密、簽名、以及驗證功能的一整套封裝。java

2.Hash(散列)算法

哈希算法將任意長度的輸入經過散列算法變換成固定長度的輸出,該輸出就是hash值,常見的有md5,sha1,sha256等。node

舉個例子:服務端將文件計算出哈希值,當客戶端下載文件也計算出哈希值,而後比對,文件是否下載完畢。假設此時的文件信息是hello world,當雙方的文件信息一致時,算出的hash值也一致。c++

node:git

const crypto = require('crypto')

//建立並返回一個 Hash 對象,該對象可用於生成哈希摘要(參數爲給定的算法)。
// const hash = crypto.createHash('md5');
const hash = crypto.createHash('sha256')
// 可任意屢次調用update():
// 指定要摘要的原始內容,能夠在摘要被輸出以前使用屢次update方法來添加摘要內容
hash.update('Hello, world!')
hash.update('Hello, nodejs!')

// 計算傳入要被哈希(使用 hash.update() 方法)的全部數據的摘要。
// 若是提供了 encoding,則返回字符串,不然返回 Buffer。
console.log(hash.digest('hex').length)
複製代碼

crypto-js:github

let crypto = require('crypto-js')
let hash = crypto.algo.SHA256.create()
hash.update('Hello, world!')
hash.update('Hello, nodejs!')
let result = hash.finalize()
// WordArray object
console.log(result.toString(crypto.enc.Hex));
複製代碼

node的Hash類:算法

crypto.createHash() 方法用於建立 Hash 實例api

Hash 類是一個實用工具,用於建立數據的哈希摘要。 它能夠經過如下兩種方式之一使用:

  • 做爲可讀寫的流,其中寫入數據以在可讀側生成計算後的哈希摘要(繼承自: </stream.Transform>)。
  • 使用 hash.update() 和 hash.digest() 方法生成計算後的哈希。

3. Hmac算法

HMAC算法將散列(hash)算法與一個密鑰結合在一塊兒,以阻止對簽名完整性的破壞,密鑰發生了變化,輸出結果也會發生變化.(Hmac能夠理解爲用隨機數「加強」的哈希算法)

仍是上面的例子換個算法

node:

let crypto = require('crypto')
// 密鑰
let key = '密鑰'
// 選定的摘要算法 sha256 選的密鑰 key
let hmac = crypto.createHmac('sha256',key)
hmac.update('Hello, world!');
hmac.update('Hello, nodejs!');
let result = hmac.digest('hex');
console.log(result)
複製代碼

crypto-js:

let CryptoJS = require('crypto-js')
// 密鑰
let key = '密鑰'
// 密鑰 keyBit 摘要算法 sha256 
let hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key);
hmac.update('Hello, world!')
hmac.update('Hello, nodejs!')
let result = hmac.finalize()
// WordArray object
console.log(result.toString(CryptoJS.enc.Hex));
複製代碼

node crypto Hmac 類:

crypto.createHmac() 方法用於建立 Hmac 實例

Hmac 類是一個實用工具,用於建立加密的 HMAC 摘要。 它能夠經過如下兩種方式之一使用:

  • 做爲可讀寫的流,其中寫入數據以在可讀側生成計算後的 HMAC 摘要(繼承自: </stream.Transform>)。

  • 使用 hmac.update() 和 hmac.digest() 方法生成計算後的 HMAC 摘要。

4.PBKDF2函數

PBKDF2:是一個用來導出密鑰的函數,經常使用於生成加密的密碼

基本原理:經過一個僞隨機函數(例如HMAC函數),把明文和一個鹽值做爲輸入參數,而後重複進行運算,並最終產生密鑰。

node:

let crypto = require('crypto')

let password = 'luoxiaobuhaha' // 用來生成密鑰的原文密碼
let salt = 'salt' // 一個加密用的鹽值。
let iterations = 10000 // 迭代次數
let keylen = 16 // 指望獲得祕鑰的長度
// 由選擇HMAC摘要算法,digest 以導出所請求的字節長度
let digest = 'sha256' // 一個僞隨機函數
crypto.pbkdf2(password, salt, iterations, keylen, digest, (err, derivedKey) => {
  if (err) throw err
  console.log(derivedKey.toString('hex'))
})
複製代碼

crypto-js:

let CryptoJS = require('crypto-js')
var derivedKey = CryptoJS.PBKDF2(password, salt, {
  keySize: 4, // // WordArray object
  iterations: iterations,
  hasher: CryptoJS.algo.SHA256
});

console.log(derivedKey.toString(CryptoJS.enc.Hex))

複製代碼

crypto.pbkdf2提供異步的基於密碼的密鑰派生功能2(PBKDF2)實現。由指定的選擇HMAC摘要算法digest被施加以導出所請求的字節長度。也有同步方法,更多細節參考文檔。

5.對稱加密

對稱加密算法,加解密都用同一個密鑰

node:

let crypto = require('crypto')
// data:須要加解密的內容,
// key: 密鑰
// 初始化向量(iv)
function aesEncrypt(data, key, iv) {
  // 給定的算法,密鑰和初始化向量(iv)建立並返回Cipher對象
  const cipher = crypto.createCipheriv('aes-192-cbc', key, iv)
  // Key length is dependent on the algorithm. In this case for aes192, it is 24 bytes (192 bits).
  // 指定要摘要的原始內容,能夠在摘要被輸出以前使用屢次update方法來添加摘要內容
  // 數據的編碼 utf8 返回值的編碼 hex
  var crypted = cipher.update(data, 'utf8', 'hex')
  crypted += cipher.final('hex')
  return crypted
}

function aesDecrypt(data, key, iv) {
  // 給定的算法,密鑰和初始化向量(iv)建立並返回Cipher對象
  const decipher = crypto.createDecipheriv('aes-192-cbc', key, iv)
  // 數據的編碼 hex 返回值的編碼 utf8
  var decrypted = decipher.update(data, 'hex', 'utf8')
  decrypted += decipher.final('utf8')
  return decrypted
}
const IV = 'f710b45f04e37709' // 初始化向量(iv)
let data = 'luoxiaobu' // 須要加解密的內容,
let key = '123456789987654321123456' // 24 位祕鑰密鑰

let encryptData = aesEncrypt(data, key, IV)
let decryptData = aesDecrypt(encryptData, key, IV)

console.log(encryptData)
console.log(decryptData)
複製代碼

輸出:

b98a1d87ea00fb47ade2d9cff0a9179d
luoxiaobu
複製代碼

crypto-js:

const CryptoJS = require('crypto-js')
const IV =  CryptoJS.enc.Utf8.parse('f710b45f04e37709') // 十六位十六進制數做爲密鑰偏移量
let data = 'luoxiaobu' // 須要加解密的內容,
let key =  CryptoJS.enc.Utf8.parse('123456789987654321123456') // 24 位祕鑰密鑰

function decrypt(data, key, iv) {
  let dataHexStr = CryptoJS.enc.Hex.parse(data);
  let dataBase64 = CryptoJS.enc.Base64.stringify(dataHexStr);
  // 接收的數據是 base64
  let decrypt = CryptoJS.AES.decrypt(dataBase64, key, { iv: iv, mode: CryptoJS.mode.CBC});
  let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
  return decryptedStr.toString();
}

//加密方法
function encrypt(data, key, iv) {
  let encrypted = CryptoJS.AES.encrypt(data, key, { iv: iv, mode: CryptoJS.mode.CBC});
  return  encrypted.ciphertext.toString().toUpperCase();;
}

let encryptData = encrypt(data, key, IV)
let decryptData = decrypt(encryptData, key, IV)

console.log(encryptData)
console.log(decryptData)
複製代碼

輸出:

b98a1d87ea00fb47ade2d9cff0a9179d
luoxiaobu
複製代碼

補充:

AES是一種經常使用的對稱加密算法。加密的分組模式有ECB/CBC/CFB/OFB

分組密碼又稱爲祕密鑰密碼或對稱密碼。利用分組密碼對明文進行加密時,首先須要對明文進行分組,每組的長度都相同,而後對每組明文分別加密獲得等長的密文,分組密碼的特色是加密密鑰與解密密鑰相同。 分組密碼的安全性應該主要依賴於密鑰,而不依賴於對加密算法和解密算法的保密。所以,分組密碼的加密和解密算法能夠公開。

node cropty Cipher 類 ,node cropty Decipher類 具體使用參考文檔

6.小結

文章是我整理出來的筆記略微粗糙,記錄crypto庫的簡單瞭解和用法,理解不許確之處,歡迎一塊兒討論學習。

關於crypto庫還經常使用的有非對稱加密算法,以及簽名,以後也會修正補上。

資料:

對稱加密和分組加密中的四種模式(ECB、CBC、CFB、OFB)

crypto-js

nodejs.org/dist/latest…

github.com/chyingp/nod…

相關文章
相關標籤/搜索