今天实现了下AES和RSA加密解密,主要的功能是对前后端交互数据进行加密解密,为什么要用到两个算法呢,首先RSA默认的话加密长度是有限的100多个byte吧大约,并且需要公钥私钥,而AES加密没有限制只需要一个key就可以,所以我们使用AES来进行数据的加解密,那么Key传递是不是会暴露,所以使用RSA对Key进行加密,前端生成RSA的公钥私钥,后端生成AES的key,前端把公钥直接发给后端,后端使用公钥将key进行加密,前端解出来key,然后使用AES对数据加密,文件也可以!
注意:这里angular使用的是Buffer来输入输出的,也就是字节数组!
1:angular加密解密环境安装
下载crypto-js、jsencrypt
npm install crypto-js
npm install --save @types/crypto-js
npm i @types/node
npm install -g npm
npm i --save-dev @types/node
npm install --save jsencrypt
< dependency> < groupId> commons-codec< /groupId> < artifactId> commons-codec< /artifactId> < version> 1.13< /version>
< /dependency>
2、Angular前端:crypto实现 AES加密
AESUtils
import { AES , enc, lib, mode, pad} from 'crypto-js' ;
import { Buffer} from 'buffer' ; export class AESUtils { public static encrypt ( buf: Buffer, key: string ) : Buffer { let key16 = enc. Utf8. parse ( key) ; var options = { mode: mode. ECB , padding: pad. Pkcs7 } ; var encryptedData = AES . encrypt ( lib. WordArray. create ( buf) , key16, options) ; return new Buffer ( encryptedData. toString ( ) , 'base64' ) ; } public static decrypt ( buf: Buffer, key: string ) : Buffer { let data = buf. toString ( 'base64' ) ; let key16 = enc. Utf8. parse ( key) ; var options = { mode: mode. ECB , padding: pad. Pkcs7 } ; var decryptedData = AES . decrypt ( data, key16, options) ; return new Buffer ( enc. Base64. stringify ( decryptedData) , 'base64' ) ; }
}
JAVA
private static String enCode ( String key, byte [ ] content) throws Exception{ SecretKeySpec skey = new SecretKeySpec ( key. getBytes ( ) , "AES" ) ; Cipher cipher = Cipher. getInstance ( ALGORITHM) ; cipher. init ( Cipher. ENCRYPT_MODE, skey) ; byte [ ] encode_content = cipher. doFinal ( content) ; return Base64. encodeBase64String ( encode_content) ; } private static byte [ ] dnCode ( String key, String content) { if ( key == null || "" . equals ( key) ) { return null; } if ( key. length ( ) != 16 ) { return null; } try { byte [ ] encode_content = Base64. decodeBase64 ( content) ; byte [ ] raw = key. getBytes ( ) ; SecretKeySpec skey = new SecretKeySpec ( raw, "AES" ) ; Cipher cipher = Cipher. getInstance ( ALGORITHM) ; cipher. init ( Cipher. DECRYPT_MODE, skey) ; return cipher. doFinal ( encode_content) ; } catch ( Exception e) { e. printStackTrace ( ) ; return null; } }
测试
html:
<!DOCTYPE HTML>
< html>
< head> < title> OutPutStream</ title> </ head>
< body> < label> 输入要加密的文本:< input id = " fs" name = " ss" type = " text" [(ngModel)] = " data" (ngModelChange) = " enTest()" > < button style =" background-color : yellow; " (click) = " enTest()" > 加密</ button> < button style =" background-color : yellow; " (click) = " deTest()" > 解密</ button> < br> 加密后的文本:< input type = " text" [(ngModel)] = " enData" disabled > < br> 解密后的文本:< input type = " text" [(ngModel)] = " unData" disabled > < br> < br> 选择要加密的文件:< form style =" background-color : olivedrab " [formGroup] = " myForm" > < input formControlName = " EDI" type = " file" class = " form-control" (change) = " handleFileSelect($event)" > </ form> < button style =" background-color : yellow; " (click) = " enFile()" > 加密文件</ button> < button style =" background-color : yellow; " (click) = " deFile()" > 解密文件</ button> < br> 加密后的文件: < input type = " text" [(ngModel)] = " enFileDataBase64" disabled > < br> < label> 解密后的文件: </ label> < button style =" background-color : yellow; " (click) = " downLoadFile()" > 下载</ button>
</ label>
</ body>
</ html>
ts:
import { Component, OnInit} from '@angular/core' ;
import FileSaver from 'file-saver' ;
import { Buffer} from 'buffer' ;
import { AESUtils} from '../base/AESUtils' ;
import { AES , enc, lib, mode, pad} from 'crypto-js' ; @Component ( { selector: 'testAES' , templateUrl: './testAES.html' , styleUrls: [ './testAES.css' ]
} ) export class TestAES implements OnInit { myForm: any ; scope: any ; constructor ( ) { } enData: any ; data: string = '' ; unData: any ; enFileData: any ; enFileDataBase64: any ; unFileData: any ; key: string = "abcdefgabcdefg12" ; JsonObj: any ; fileName: string ; ngOnInit ( ) : void { } handleFileSelect ( evt) { const files = evt. target. files; const f = files[ 0 ] ; const reader = new FileReader ( ) ; reader. readAsArrayBuffer ( f) ; reader. onload = ( f => { this . fileName = f. name; return e => { this . JsonObj = e. target. result; } ; } ) ( f) ; } public encrypt1 ( buf? : Buffer, key? : string ) : Buffer { let buffer = new Buffer ( [ 98 , 99 , - 22 , - 44 ] ) ; console . log ( buffer. toString ( 'base64' ) ) ; let key16 = enc. Utf8. parse ( this . key) ; var options = { mode: mode. ECB , padding: pad. Pkcs7 } ; var encryptedData = AES . encrypt ( lib. WordArray. create ( buffer) , key16, options) ; let buffer1 = new Buffer ( encryptedData. toString ( ) , 'base64' ) ; console . log ( buffer1) ; console . log ( encryptedData. toString ( ) ) ; return } public decrypt1 ( buf? : Buffer, key? : string ) : Buffer { let aaa = "TsA8sxb3ftE9s850oyueSQ==" ; let buffer1 = new Buffer ( [ - 22 ] ) ; let s = buffer1. toString ( 'base64' ) ; let key16 = enc. Utf8. parse ( this . key) ; var options = { mode: mode. ECB , padding: pad. Pkcs7 } ; let cipherParams = lib. CipherParams. create ( buffer1) ; var decryptedData = AES . decrypt ( s, key16, options) ; let buffer = new Buffer ( enc. Base64. stringify ( decryptedData) , 'base64' ) ; console . log ( decryptedData. words) ; console . log ( buffer) ; console . log ( buffer. toString ( 'base64' ) ) ; } enTest ( ) { let a = AESUtils. encrypt ( new Buffer ( [ 2 , 7 , 234 , 97 ] ) , this . key) ; console . log ( a. toString ( "base64" ) ) ; } deTest ( ) { let a = AESUtils. decrypt ( new Buffer ( "KJncoeWOUvKEQlfcE6KQLQ==" , 'base64' ) , this . key) ; console . log ( a) ; } enFile ( ) { this . enFileData = AESUtils. encrypt ( this . JsonObj, this . key) ; this . enFileDataBase64 = this . enFileData. toString ( 'base64' ) ; } deFile ( ) { this . unFileData = AESUtils. decrypt ( this . enFileData, this . key) ; } downLoadFile ( ) { const blob = new Blob ( [ this . unFileData] , { type : 'F:\\my-app\\src\\app\\;charset=utf-8' } ) ; FileSaver. saveAs ( blob, this . fileName) ; }
}
3、jsencrypt实现rsa
RSAUtils
import { Buffer} from 'buffer' ;
import { JSEncrypt} from 'jsencrypt/lib' ; declare var RSAUtil: any ; export class RSAUtils { private static jsEncrypt: JSEncrypt = new JSEncrypt ( { } ) ; public static getRSAKeys ( ) { let publicKey = this . jsEncrypt. getKey ( ) . getPublicBaseKeyB64 ( ) ; let privateKey = this . jsEncrypt. getKey ( ) . getPrivateBaseKeyB64 ( ) ; return { publicKey, privateKey} ; } public static encodeRSA ( buf: Buffer, publicKey: string ) : Buffer { let str = buf. toString ( 'base64' ) ; this . jsEncrypt. setPublicKey ( publicKey) ; let encrypt = this . jsEncrypt. encrypt ( str) ; return new Buffer ( encrypt, 'base64' ) ; } public static decodeRSA ( buf: Buffer, privateKey: string ) : Buffer { let str = buf. toString ( 'base64' ) ; this . jsEncrypt. setPrivateKey ( privateKey) ; let decrypt = this . jsEncrypt. decrypt ( str) ; return new Buffer ( decrypt, 'base64' ) ; } }
JAVA:
public static String encrypt ( String str, String publicKey) throws Exception{ byte [ ] decoded = Base64. decodeBase64 ( publicKey) ; RSAPublicKey pubKey = ( RSAPublicKey) KeyFactory. getInstance ( "RSA" ) . generatePublic ( new X509EncodedKeySpec ( decoded) ) ; Cipher cipher = Cipher. getInstance ( "RSA" ) ; cipher. init ( Cipher. ENCRYPT_MODE, pubKey) ; return Base64. encodeBase64String ( cipher. doFinal ( str. getBytes ( StandardCharsets. UTF_8) ) ) ; } public static String decrypt ( String str, String privateKey) throws Exception{ byte [ ] inputByte = Base64. decodeBase64 ( str. getBytes ( StandardCharsets. UTF_8) ) ; byte [ ] decoded = Base64. decodeBase64 ( privateKey) ; RSAPrivateKey priKey = ( RSAPrivateKey) KeyFactory. getInstance ( "RSA" ) . generatePrivate ( new PKCS8EncodedKeySpec ( decoded) ) ; Cipher cipher = Cipher. getInstance ( "RSA" ) ; cipher. init ( Cipher. DECRYPT_MODE, priKey) ; return new String ( cipher. doFinal ( inputByte) ) ; }
测试
输入要加密的文本:
< input id = " fs1" name = " ss" type = " text" [(ngModel)] = " data" (ngModelChange) = " encrypt()" >
< button style =" background-color : yellow; " (click) = " encrypt()" > 加密</ button>
< button style =" background-color : yellow; " (click) = " decrypt()" > 解密</ button> < br>
加密的后的文本:< input id = " fs2" name = " ss" type = " text" [(ngModel)] = " enData" > < br>
解密的后的文本:< input id = " fs3" name = " ss" type = " text" [(ngModel)] = " unData" >
import { Component, OnInit} from '@angular/core' ;
import { Buffer} from 'buffer' ;
import { RSAUtils} from '../base/RSAUtils' ;
import FileSaver from 'file-saver' ; @Component ( { selector: 'app-rsa' , templateUrl: './rsa.html' , styleUrls: [ './rsa.css' ]
} )
export class Rsa implements OnInit { enData: any ; data: string = '' ; unData: any ; PRIVATE_KEY_CODE = "" ; PUBLIC_KEY_CODE = "" ; enFileDataBase64: any ; enFileData: any ; fileName: string ; JsonObj: any ; unFileData: any ; constructor ( ) { } ngOnInit ( ) : void { this . getKeys ( ) ; } getKeys ( ) { let rsaKeys = RSAUtils. getRSAKeys ( ) ; this . PUBLIC_KEY_CODE = rsaKeys. publicKey; this . PRIVATE_KEY_CODE = rsaKeys. privateKey; } encrypt ( ) { let buffer = new Buffer ( this . data) ; let buf = RSAUtils. encodeRSA ( buffer, this . PUBLIC_KEY_CODE ) ; let s = buf. toString ( 'base64' ) ; this . enData = s; } decrypt ( ) { this . unData = RSAUtils. decodeRSA ( this . enData, this . PRIVATE_KEY_CODE ) ; console . log ( this . unData) ; }
}