使用RSA實現前端公鑰加密後端私鑰解密

項目中在用戶登陸時須要進行用戶名和密碼加密,這裏選用了RSA非對稱加密的方式.javascript

  • 公鑰私鑰:OpenSSL的公鑰私鑰(Node crypto模塊限制)
  • 前端: jsencrypt庫加密
  • 後端: Node crypto模塊

使用openssl生成公鑰私鑰

linux生成公鑰私鑰命令:前端

genrsa -out rsa_private_key.pem 1024 // 生成1024位私鑰
pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM –nocrypt // 把RSA私鑰轉換成PKCS8格式
rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem // 生成對應公鑰

這裏已經生成了公鑰和私鑰,公鑰私鑰的使用能夠分爲兩種方式java

  1. 在使用時使用fs.readFileSync()來讀取
  2. 直接將公私鑰拷貝出來放到配置文件中(私鑰要保證正確的換行格式,不然crypto不能正確的使用私鑰,能夠在每行末尾添加\n\來確保格式正確)

前端使用jsencrypt庫加密

這個庫能夠使用模塊加載的方式使用,下面的代碼也是使用這種方式,固然也能夠在頁面中經過<script>標籤引入,這種方式的使用請參考庫的具體文檔linux

const JSEncrypt = require("jsencrypt"); // 引入模塊
const str = "i will be encrypto";
const encrypt = new JSEncrypt.JSEncrypt(); // 實例化加密對象
encrypt.setPublicKey(publicKey); // 設置公鑰
const encryptoPasswd = encrypt.encrypt(str) // 加密明文

服務端使用Node crypto模塊解密

解密函數實現npm

function rsaDecrypt(text) {
    const privateKey = config.privateKey;
    let textBuffer, decryptText;
    try {
        textBuffer= new Buffer(text, "base64"); // jsencrypt 庫在加密後使用了base64編碼,因此這裏要先將base64編碼後的密文轉成buffer
        decryptText= crypto.privateDecrypt({
            key: new Buffer(privateKey), // 若是經過文件方式讀入就沒必要轉成Buffer
            padding: constants.RSA_PKCS1_PADDING // 由於前端加密庫使用的RSA_PKCS1_PADDING標準填充,因此這裏也要使用RSA_PKCS1_PADDING 
        }, textBuffer).toString();
    } catch (err) {
        throw (new CommonError("errorMsg", errorCode));
    }
    return decryptText;
}
相關文章
相關標籤/搜索