[英]symmetric and asymmetric encryption between Angular 2 and Spring Boot
我需要從Angular App向Spring Boot后端發送密碼,並且需要對該密碼進行加密。 我嘗試使用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都是如此。 JavaScript代碼:
let encryptedText = pubKey.encrypt(this.forgeService.encodeUTF8("Some text"));//<-- Encrypt "Some text"
當我在網絡中發送加密的文本時,我不知道是否有什么東西丟失(更改)。
我相信您在編碼數據方面(以及其他方面)存在基本問題
let encryptAesKey = pubKey.encrypt(aesKey.toString());
您正在加密密鑰的字符串表示形式(而不是密鑰本身),並且我相信JS以十六進制格式返回toString()(如果我錯了,請糾正我)。 結果將是原始密鑰的兩倍。
在我使用Java時,您嘗試解密字節數組中的加密十六進制字符串rssult,它不符合預期的256位大小
編輯:
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.PRIVATE_KEY, privateKey);
是錯誤的,您必須使用密碼。 DECRYPT_MODE。
下一個 :
String aesKey = new String(cipher.doFinal(..
請勿從鍵中創建字符串(要打印時進行編碼)),請將其保留為字節數組。這將丟失不可打印的值。
您應該特定於加密模式
Cipher cipher = Cipher.getInstance("rsa/ecb/nopadding");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.