angular和JAVA实现aes、rsa加密解密,前后端交互,前端加解密和后端JAVA加解密实现
·
今天实现了下AES和RSA加密解密,主要的功能是对前后端交互数据进行加密解密,为什么要用到两个算法呢,首先RSA默认的话加密长度是有限的100多个byte吧大约,并且需要公钥私钥,而AES加密没有限制只需要一个key就可以,所以我们使用AES来进行数据的加解密,那么Key传递是不是会暴露,所以使用RSA对Key进行加密,前端生成RSA的公钥私钥,后端生成AES的key,前端把公钥直接发给后端,后端使用公钥将key进行加密,前端解出来key,然后使用AES对数据加密,文件也可以!
注意:这里angular使用的是Buffer来输入输出的,也就是字节数组!
1:angular加密解密环境安装
下载crypto-js、jsencrypt
# crypto-js
npm install crypto-js
npm install --save @types/crypto-js
npm i @types/node
#更新npm,下载完crypto-js提示让更新
npm install -g npm
npm i --save-dev @types/node
#jsencrypt
npm install --save jsencrypt
#Base64编码的jar
<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 {
/**
* @param buf 字节数组
* @param key key
*
* 传入字节数组和key,返回加密后的字节数组
*/
public static encrypt(buf: Buffer,key:string): Buffer {
let key16 = enc.Utf8.parse(key); //将key转成16进制,如果不转解密也不能转并且加密后的数组动态的(如果有,解密必须有)
var options = {
mode: mode.ECB, //模式
padding: pad.Pkcs7 //补码方式
};
var encryptedData = AES.encrypt(lib.WordArray.create(buf), key16, options); //加密
return new Buffer(encryptedData.toString(), 'base64'); //解密后是base64的字符串,转为buff(字节数组)返回
}
public static decrypt(buf: Buffer,key:string): Buffer {
let data = buf.toString('base64'); //将字节转为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); //根据指定算法ALGORITHM自成密码器
cipher.init(Cipher.ENCRYPT_MODE, skey); //初始化密码器,第一个参数为加密(ENCRYPT_MODE)或者解密(DECRYPT_MODE)操作,第二个参数为生成的AES密钥
byte [] encode_content = cipher.doFinal(content); //密码器加密数据
return Base64.encodeBase64String(encode_content);
}
private static byte[] dnCode(String key,String content){ //content是base64编码字符串
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"); //根据密码生成AES密钥
Cipher cipher = Cipher.getInstance(ALGORITHM); //根据指定算法ALGORITH生成密码器
cipher.init(Cipher.DECRYPT_MODE, skey); //初始化密码器,第一个参数为加密(ENCRYPT_MODE)或者解密(DECRYPT_MODE)操作,第二个参数为生成的AES密钥
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>
<!--<input type="file" id="fileUpload" value="选择文件" mce_style="display:none" οnchange="angular.element(this).scope().fileChoose(this)" >-->
<!--<button (click)="chaunshu()" class="btn btn-default">转移</button>-->
</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); //将key转成16进制,如果不转解密也不能转并且加密后的数组动态的(如果有,解密必须有)
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 //解密后是base64的字符串,转为buff(字节数组)返回
}
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'); //获取到加密后的base64字符
}
deFile() {
this.unFileData = AESUtils.decrypt(this.enFileData,this.key); // 解密,解密出来的是buffer
}
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({});
/**
* @param buf 字节数组
* @param key key
*
* 传入字节数组和key,返回加密后的字节数组
*/
public static getRSAKeys() {
let publicKey = this.jsEncrypt.getKey().getPublicBaseKeyB64();
let privateKey = this.jsEncrypt.getKey().getPrivateBaseKeyB64();
return {publicKey, privateKey};
}
//传入Buffer,返回Buffer
public static encodeRSA(buf: Buffer, publicKey: string): Buffer {
let str = buf.toString('base64'); //将传入的buf转为base64(加一层base64,因为这个方法只能传String)
this.jsEncrypt.setPublicKey(publicKey);
let encrypt = this.jsEncrypt.encrypt(str);
return new Buffer(encrypt, 'base64');
}
//传入Buffer,返回Buffer
public static decodeRSA(buf: Buffer, privateKey: string): Buffer {
let str = buf.toString('base64'); //将需要解密的Buffer转为base64字符串再解密
this.jsEncrypt.setPrivateKey(privateKey);
let decrypt = this.jsEncrypt.decrypt(str);
return new Buffer(decrypt, 'base64'); //解密后转为Buffer(这里解的是最开始套的base64,因为底层加密只能用字符串)
}
}
JAVA:
public static String encrypt(String str, String publicKey) throws Exception{//key是16位str
//base64编码的公钥
byte[] decoded = Base64.decodeBase64(publicKey);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
//RSA加密
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{
//64位解码加密后的字符串
byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
//base64编码的私钥
byte[] decoded = Base64.decodeBase64(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
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');
// console.log(strB64);
this.enData = s;
}
decrypt(){
this.unData = RSAUtils.decodeRSA(this.enData,this.PRIVATE_KEY_CODE);
console.log(this.unData);
}
}
更多推荐
所有评论(0)