有關數據加密解密問題,有很多鍾加密方式。這里我就講我最近使用到的其中的兩種方法
一、首先第一種就是RAS的加密形式,我使用這種加密形式最要是看中他的16進制加密形式類似MD5的形式,機密以后的字符串沒有特殊字符
1、首先我們看html部分,我們要先導入所需要的加密JS文件
<script src="{_TEMP_PUBLIC_}/rasEncrypt/jsbn.js" type="text/javascript"></script> <script src="{_TEMP_PUBLIC_}/rasEncrypt/prng4.js" type="text/javascript"></script> <script src="{_TEMP_PUBLIC_}/rasEncrypt/rng.js" type="text/javascript"></script> <script src="{_TEMP_PUBLIC_}/rasEncrypt/rsa.js" type="text/javascript"></script> <div class="portlet light"> <div class="portlet-title"> <div class="caption">測試加密信息</div> </div><!-- portlet-title --> <div class="portlet-body form"> <form action="/test/testData" method="post" class="form-horizontal form-row-seperated" id="three-from" novalidate="novalidate" name="three-from"> <div class="form-body clearfix"> <div class="form-group form-md-line-input"> <label class="col-xs-2 control-label" for="password">加密字符串</label> <div class="col-xs-10"> <input class="form-control" type="password" name="password" value="01234567893265316259" placeholder="請輸入加密字符串" id="password"> <div class="form-control-focus"> </div> </div><!-- col-xs-10 --> </div> <div class="form-actions"> <div class="row"> <div class="col-md-offset-2 col-md-10"> <button type="submit" class="btn blue" id="subForm"><i class="fa fa-check"></i> 提交</button> </div> </div> </div> </div> </form> </div> <!-- form-body clearfix --> </div> <script type="text/javascript"> function subForm() {//建議是在表單提交的瞬間去加密,下面的寫法是只要是password都進行加密 //如果這個加密方式是一個函數才進行加密,這樣是防止你以前寫的沒有加密到保證文件不會報錯 if(typeof(RSAKey) == 'function') { $("input[type='password']").each(function (i, e) { var rsa = new RSAKey(); var pwd = $(e).val(); var res = rsa.encrypt(pwd); $(e).val(res).data('rpwd', pwd); }); } } </script>
2、接着我們就要注意到JS加載的其中一個文件的配置了
// Depends on jsbn.js and rng.js // Version 1.1: support utf-8 encoding in pkcs1pad2 // convert a (hex) string to a bignum object function parseBigInt(str,r) { return new BigInteger(str,r); } function linebrk(s,n) { var ret = ""; var i = 0; while(i + n < s.length) { ret += s.substring(i,i+n) + "\n"; i += n; } return ret + s.substring(i,s.length); } function byte2Hex(b) { if(b < 0x10) return "0" + b.toString(16); else return b.toString(16); } // PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint function pkcs1pad2(s,n) { if(n < s.length + 11) { // TODO: fix for utf-8 alert("Message too long for RSA"); return null; } var ba = new Array(); var i = s.length - 1; while(i >= 0 && n > 0) { var c = s.charCodeAt(i--); if(c < 128) { // encode using utf-8 ba[--n] = c; } else if((c > 127) && (c < 2048)) { ba[--n] = (c & 63) | 128; ba[--n] = (c >> 6) | 192; } else { ba[--n] = (c & 63) | 128; ba[--n] = ((c >> 6) & 63) | 128; ba[--n] = (c >> 12) | 224; } } ba[--n] = 0; var rng = new SecureRandom(); var x = new Array(); while(n > 2) { // random non-zero pad x[0] = 0; while(x[0] == 0) rng.nextBytes(x); ba[--n] = x[0]; } ba[--n] = 2; ba[--n] = 0; return new BigInteger(ba); } // "empty" RSA key constructor function RSAKey() {
//千萬要注意這里的公鑰配置一定要與密鑰是一對,生成modulus的方法我會在下面介紹 var N="DB1EA572B55F5D9C8ADF092F5DCC3559CFEA8CE8BB54E3A71DA9B1AFBD7D17CF80ADB224FE4EA5379BC782F41C137748D8F1B5A36AD62A127EF5E87EFB25C209A66BCEE9925CE09631BF2271E81123E93438646625080FF04F4F2CF532B077E3E390486DF40E7586F0AE522C873F33170222F46BDB6084F55DE6B7031E55DBE7"; this.n = parseBigInt(N,16);
//注意我們這里使用的是10001是十六進制 this.e = parseInt("10001",16); this.d = null; this.p = null; this.q = null; this.dmp1 = null; this.dmq1 = null; this.coeff = null; } // Set the public key fields N and e from hex strings function RSASetPublic(N,E) { if(N != null && E != null && N.length > 0 && E.length > 0) { this.n = parseBigInt(N,16); this.e = parseInt(E,16); } else alert("Invalid RSA public key"); } // Perform raw public operation on "x": return x^e (mod n) function RSADoPublic(x) { return x.modPowInt(this.e, this.n); } // Return the PKCS#1 RSA encryption of "text" as an even-length hex string function RSAEncrypt(text) { var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3); if(m == null) return null; var c = this.doPublic(m); if(c == null) return null; var h = c.toString(16); if((h.length & 1) == 0) return h; else return "0" + h; } // Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string //function RSAEncryptB64(text) { // var h = this.encrypt(text); // if(h) return hex2b64(h); else return null; //} // protected RSAKey.prototype.doPublic = RSADoPublic; // public RSAKey.prototype.setPublic = RSASetPublic; RSAKey.prototype.encrypt = RSAEncrypt; //RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
3、最后就是我們的PHP文件機密代碼了
/*如果多處使用最好是定義一個常量*/ define("RASKEY","-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQDbHqVytV9dnIrfCS9dzDVZz+qM6LtU46cdqbGvvX0Xz4CtsiT+ TqU3m8eC9BwTd0jY8bWjatYqEn716H77JcIJpmvO6ZJc4JYxvyJx6BEj6TQ4ZGYl CA/wT08s9TKwd+PjkEht9A51hvCuUiyHPzMXAiL0a9tghPVd5rcDHlXb5wIDAQAB AoGBANhrD2wZWYSi7cJWVxMkc3kuUvIzl3rDkrZIeXgjBp9y0hw8fC80zBf9Y3Oi 2Owc/7VOHmG2TqqlNAJ7TJePdnGvEG5yzHuMH6/uRPS4A+gDndM8U/sZBUYaZjbr 5M8vg6wL3yQ2awAbXu7pwLEvxVmuvhv+0jOFnqLpTRlki3ZpAkEA+Y00pTwikCEt N+dkFGbhzZfH6bFNIkUOCrkDMgru1IargO/ggllk4fVLe7WBMWwh/0X9oTeTjLi7 Es856QMdpQJBAODIIeu7/cL3wp6Bigg7V25OSD+7uSjlCpoPSUNZIjZ6HJQsFCnU RHsEDeD1f88g7i9AGI0htYiJXCgwd6GE9ZsCQGoCUhrfMM+JSGw3H4yLJ+DuWT4s 01d7fjuP3IulmU8u5iwfun+k+fYC/c3PjNIx3T9TvCqAMW3WC6Ix5afWawECQA6p n2TUL3pvVPen9YwR6uMcIiReJ3becfGYu6uz/cJV9tVHhs0vtoPbwNgCy6KEQGU+ phtWrpPIegV5G+SiWq8CQQCoH+ic1j9b1DzENUb206w7KpcIhm629iUWUgBTrnlC LzOA6xwY78V7cAUdzhTycAxhmWq/1FBlCCKtuZHVHnE/ -----END RSA PRIVATE KEY-----"); /*接到的表單參數*/ $password = trim($this->options['password']); /*這里的判斷是防止沒有加密,或是不是這個加密形式的密碼進行解密*/ if(strlen($password) == 256){ $encrypt_data = pack("H*", $password);//對十六進制數據進行轉換 /*openssl的十六進制解密*/ if(openssl_private_decrypt($encrypt_data, $decrypt_data, RASKEY)){ $password = $decrypt_data; } }
4、生成公約和私鑰的方法
二、RSA密鑰生成命令 1、生成RSA私鑰 openssl>openssl genrsa -out rsa_private_key.pem 1024 得到exponent: 10001 2、生成modulus: openssl>openssl rsa -in rsa_private_key.pem -noout -modulus 3、生成RSA公鑰 openssl>openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 4、將RSA私鑰轉換成PKCS8格式(==========java使用===========) openssl>openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt 注意:“>”符號后面的才是需要輸入的命令。
二、基於crypto-js的加密和PHP對此加密的解密及相同加密方式,這種加密缺點就是加密后的密文存在特殊字符
1、手續我看看html的文件
<div class="portlet light"> <div class="portlet-title"> <div class="caption">測試加密信息</div> </div><!-- portlet-title --> <div class="portlet-body form"> <form action="/test/testData" method="post" class="form-horizontal form-row-seperated" id="three-from" novalidate="novalidate" name="three-from"> <div class="form-body clearfix"> <div class="form-group form-md-line-input"> <label class="col-xs-2 control-label" for="password">加密字符串</label> <div class="col-xs-10"> <input class="form-control" type="password" name="password" value="01234567893265316259" placeholder="請輸入加密字符串" id="password"> <div class="form-control-focus"> </div> </div><!-- col-xs-10 --> </div> <div class="form-actions"> <div class="row"> <div class="col-md-offset-2 col-md-10"> <button type="submit" class="btn blue" id="subForm"><i class="fa fa-check"></i> 提交</button> </div> </div> </div> </div> </form> </div> <!-- form-body clearfix --> </div> <script src="http://cdn.bootcss.com/crypto-js/3.1.9/crypto-js.js"></script> <script> var data = "en2JprK0nMyYgbd6dQO0O0OO0O0O" // 需要加密的字符串 var key_base="contentWindowHig"; // 加密秘鑰的基值 var iv_base="contentDocuments"; // 加密所需iv基值 /** * 定義加密函數 * @param {[type]} a [形參,需要加密的值] * @return {[type]} [加密后的值] */ var get=function(a){ var key=CryptoJS.enc.Utf8.parse(key_hash); var iv=CryptoJS.enc.Utf8.parse(iv_base); var res=CryptoJS.AES.encrypt(a,key,{iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.ZeroPadding}); return res.toString() } </script>
2、PHP解密方法
// 定義變量 $pass = "en2JprK0nMyYgbd6dQO0O0OO0O0O"; $key_base = "contentWindowHig"; $iv_base = "contentDocuments"; // 解密 $pass = str_replace(' ','+',$pass); $encryptedData = base64_decode($pass); $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key_base, $encryptedData, MCRYPT_MODE_CBC, $iv_base); $decrypted =trim($decrypted);