我需要从Angular App发送密码到Spring启动后端,我需要加密这个密码。我尝试使用AES加密密码和RSA加密AES生成的密钥,但我不知道如何做到这一点。 我的代码: Angular 2 Side:
EncryptService:
public generateRandomKey( keyLength: number){
let chars =
`0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmn
opqrstuvwxyz*&-%/!?*+=()`;
let stringKey = "";
for (let i=0; i < keyLength; i++) {
var rnum = Math.floor(Math.random() * chars.length);
stringKey += chars.substring(rnum,rnum+1);
}
return stringKey;
}
public aesEncrypt( phrase: string ){
let key = this.generateRandomKey(50);
let aesEncrypt = cryptojs.AES.encrypt(phrase, key);
let aesKey = aesEncrypt.key
let aesIv = aesEncrypt.iv;
let encryptMessage = aesEncrypt.toString();
return [encryptMessage, aesKey, aesIv];
}
public buildPubkFromPem( pem: string ){
return forge.pki.publicKeyFromPem(pem);
}
组件:
let pubKey = this.encryptService.buildPubkFromPem(environment.publicKey);
let data = this.encryptService.aesEncrypt(map.passwd);
let passwdEncrypt = data[0];
let aesKey = data[1];
let encryptAesKey = pubKey.encrypt(aesKey.toString());
this.pendingRequestService
.send({'passwd': passwdEncrypt, 'encryptAesKey': encryptAesKey)
.finally(()=>{this.popupSignService.isLoading = false;})
.subscribe(
result => {
console.log("OK", result);
}
);
}
后端方面: 控制器:
public ResponseEntity signDocs(
@RequestParam(value = "passwd") String passwd,
@RequestParam(value = "encryptAesKey") String encryptAesKey,
){
try{
signatureService.decryptMessage(passwd, encryptAesKey);
}catch( Exception ex ){
ex.printStackTrace();
}
服务:
public String decryptMessage( String encrypMsg, String encryptAesKey ){
// Load private key from P12
ClassPathResource pkcs12 = new ClassPathResource("ssl/file.p12");
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(pkcs12.getInputStream(), p12Password.toCharArray());
String alias = (String)keystore.aliases().nextElement();
PrivateKey privateKey = (PrivateKey) keystore.getKey(alias, p12Password.toCharArray());
// Decrypt
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.PRIVATE_KEY, privateKey);
System.out.println(encryptAesKey);
byte[] doFinal = cipher.doFinal(encryptAesKey.getBytes());
String aesKey = new String(cipher.doFinal(Base64.decodeBase64(encryptAesKey)), "UTF-8");
return aesKey;
}
当我尝试解密AES加密密钥时:
javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes
我认为加密AES密钥时它是相关的。 有人能帮助我吗? 提前谢谢。
修改
如果我使用伪造加密带有公钥的字符串“Some text”,并将加密文本发送到后端不起作用。如果我使用相同的公钥和私钥从javascript到javascript和java到java进行ecrypt和解密。 Javascript代码:
let encryptedText = pubKey.encrypt(this.forgeService.encodeUTF8("Some text"));//<-- Encrypt "Some text"
当我在网络中发送加密文本时,我不知道是否有东西丢失(改变)。
答案 0 :(得分:0)
我相信你有编码数据的基本问题(和其他人一样)
let encryptAesKey = pubKey.encrypt(aesKey.toString());
你正在加密密钥的字符串表示(而不是密钥本身),我相信JS以十六进制格式返回toString()(如果我错了,请纠正我)。结果将是原始密钥的两倍。
而我是Java你试图在字节数组中解密加密的十六进制字符串rssulting,这不符合预期的256位大小
编辑:
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.PRIVATE_KEY, privateKey);
错了,你必须使用Cipher。 DECRYPT_MODE。
下一个:
String aesKey = new String(cipher.doFinal(..
不要从密钥中创建一个字符串(当你想打印它时进行编码),将其保存为字节数组。你正在失去不可打印的价值观。
您应该具体使用加密模式
Cipher cipher = Cipher.getInstance("rsa/ecb/nopadding");