一套简单的基于-RSA-AES-加密机制的前端解决方案

前言因公司现有后台管理系统项目需对部分网络请求接口的重要数据进行加密,整合了一套简单的基于 RSA + AES 加密机制的前端解决方案。 参考文献:crypto 廖雪峰crypto-js aes 加解密rsa 加解密参考 API:crypto-jsJSEncrypt依赖crypto-js: npm i crypto-jsJSEncrypt:npm i jsencrypt加密流程先上图 因项目为后台管理系统,所以这里会有两种业务场景:用户在未登录前是没有鉴权 token 的,需在成功登录并获取 token 后和 encryptKey 一并上传后端,后端才能将 token 与 encryptKey 做绑定。用户已登录成功,页面刷新后将会重新生成 aesKey ,这时候需从 cookie 中获取 token 并和 encryptKey 上传后端,后端重新绑定 token 和 encryptKey。代码encryption.js 封装import CryptoJS from 'crypto-js'import JSEncrypt from 'jsencrypt'const encryptor = new JSEncrypt()// 生成 AESKEYexport const aesKey = createAesKey()export function createAesKey () { const expect = 16 let str = Math.random().toString(36).substr(2) while (str.length < expect) { str += Math.random().toString(36).substr(2) } str = str.substr(0, 16) return str}/** * AES 加密 * @param word 待加密字段 * @param keyStr 加密 key * @returns {string} 返回加密字段 */export function aesEncrypt (word, keyStr) { keyStr = keyStr || aesKey console.log(keyStr) const key = CryptoJS.enc.Utf8.parse(keyStr) let srcs = '' switch (typeof (word)) { case 'string': srcs = CryptoJS.enc.Utf8.parse(word) break case 'object': srcs = CryptoJS.enc.Utf8.parse(JSON.stringify(word)) break default: srcs = CryptoJS.enc.Utf8.parse(word.toString()) } const encrypted = CryptoJS.AES.encrypt(srcs, key, {iv: key, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7}) return encrypted.toString()}/** * AES 解密 * @param word 待解密数据 * @param keyStr 解密 key * @returns {string} 返回解密字符串 */export function aesDecrypt (word, keyStr) { keyStr = keyStr || aesKey const key = CryptoJS.enc.Utf8.parse(keyStr) const decrypt = CryptoJS.AES.decrypt(word, key, { iv: key, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }) return CryptoJS.enc.Utf8.stringify(decrypt).toString()}/** * RSA 设置公钥 * @param val 公钥 */export function setPublicKey (val) { encryptor.setPublicKey(val)}/** * RSA 加密 * @param data 待加密数据 * @returns {PromiseLike<ArrayBuffer>} 返回加密字符串 */export function rsaEncrypt (data) { return encryptor.encrypt(data)}总结AES 加解密涉及到的模式(如 CBC、ECB 等)、偏移量和填充等,请参考文中前言提及的文献和 API本文仅为解决方案参考,请结合实际业务需求及业务场景自由发挥 ...

June 5, 2019 · 2 min · jiezi

Go语言cryptossh执行远程命令

前言远程执行命令有什么用?为什么要远程执行命令? 如果你只有2,3台服务器需要管理的时候,远程执行命令确实没有没多大作用,你可以登录到每台服务器上去完成各种操作。 当你的服务器大于3台的时候,远程执行的命令的方式就可以大大提高你的生产力了。 如果你有一个可以远程执行命令的工具,那么就可以像操作单台机器那样操作多台机器,机器越多,效率提高的越多。 远程执行命令最常用的方法就是利用 SSH 协议,将命令发送到远程机器上执行,并获取返回结果。 代码连接包含了认证,可以使用 password 或者 sshkey 2种方式来认证。下面的示例为了简单,使用了密码认证的方式来完成连接。 package mainimport ( "fmt" "github.com/mitchellh/go-homedir" "golang.org/x/crypto/ssh" "io/ioutil" "log" "time")func main(){ sshHost := "home.xxx.cn" sshUser := "x" sshPassword := "xxxxxx" sshType := "password"//password 或者 key sshKeyPath := ""//ssh id_rsa.id 路径" sshPort := 22 //创建sshp登陆配置 config := &ssh.ClientConfig{ Timeout: time.Second,//ssh 连接time out 时间一秒钟, 如果ssh验证错误 会在一秒内返回 User: sshUser, HostKeyCallback: ssh.InsecureIgnoreHostKey(), //这个可以, 但是不够安全 //HostKeyCallback: hostKeyCallBackFunc(h.Host), } if sshType == "password" { config.Auth = []ssh.AuthMethod{ssh.Password(sshPassword)} } else { config.Auth = []ssh.AuthMethod{publicKeyAuthFunc(sshKeyPath)} } //dial 获取ssh client addr := fmt.Sprintf("%s:%d", sshHost, sshPort) sshClient, err := ssh.Dial("tcp", addr, config) if err != nil { log.Fatal("创建ssh client 失败",err) } defer sshClient.Close() //创建ssh-session session, err := sshClient.NewSession() if err != nil { log.Fatal("创建ssh session 失败",err) } defer session.Close() //执行远程命令 combo,err := session.CombinedOutput("whoami; cd /; ls -al;echo https://github.com/dejavuzhou/felix") if err != nil { log.Fatal("远程执行cmd 失败",err) } log.Println("命令输出:",string(combo))}func publicKeyAuthFunc(kPath string) ssh.AuthMethod { keyPath, err := homedir.Expand(kPath) if err != nil { log.Fatal("find key's home dir failed", err) } key, err := ioutil.ReadFile(keyPath) if err != nil { log.Fatal("ssh key file read failed", err) } // Create the Signer for this private key. signer, err := ssh.ParsePrivateKey(key) if err != nil { log.Fatal("ssh key signer failed", err) } return ssh.PublicKeys(signer)}代码详解1 配置ssh.ClientConfig建议TimeOut自定义一个比较端的时间自定义HostKeyCallback 如果像简便就使用 ssh.InsecureIgnoreHostKey回调, 这种方式不是很安全publicKeyAuthFunc 如果使用key登陆 就需要着用这个函数量读取id_rsa私钥,当然你可以自定义这个访问让他支持字符串2 ssh.Dial创建ssh客户端拼接字符串得到ssh连接地址,同时不要忘记 defer client.Close() ...

May 21, 2019 · 2 min · jiezi