簡體   English   中英

Angular 2和Spring Boot之間的對稱和非對稱加密

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM