天天看點

開發必備:多種語言實作AES加密解密示例保證資料安全傳輸與存儲

作者:好呀魚

在軟體開發過程,為保證資料傳輸和存儲安全,加密是一種重要的技術手段。其中,AES(Advanced Encryption Standard)是一種常用的對稱加密算法,它可以通過不同的模式和填充方式來滿足不同的加密需求。

在本文中,我們将重點介紹 AES 加密算法的 ECB 模式和 PKCS5Padding 填充方式,以及如何在 Js、Java 、Python、Node.js等幾種常用程式設計語言中實作加密和解密的過程。

  • ECB 模式:ECB(Electronic Codebook)模式是最簡單的 AES 加密模式之一。它将明文分割成固定大小的資料塊,并對每個資料塊分别進行加密。每個資料塊之間是獨立的,是以,相同的明文塊将始終生成相同的密文塊。
  • PKCS5Padding 填充方式:一種常用的填充方式,用于将資料塊調整為固定長度的倍數。在 AES 加密中,資料塊長度通常為 128 位(16 位元組),如果明文長度不是塊長度的整數倍,就需要使用填充方式進行補位。例如,如果需要補位 5 個位元組,就會使用值為 0x05 的位元組進行填充。
開發必備:多種語言實作AES加密解密示例保證資料安全傳輸與存儲

JS版本

開發必備:多種語言實作AES加密解密示例保證資料安全傳輸與存儲

在 JavaScript 中使用 CryptoJS 庫進行 AES/ECB/PKCS5Padding 加密時,你可以按照以下方式進行操作:

通過 npm 安裝 crypto-js:

npm install crypto-js           

示例代碼:

import CryptoJS from 'crypto-js';

// 明文
const plaintext ='{"objectName":"test","pageNo":0,"pageSize":10}'
 // 密鑰,使用者自定義
const key = '1234567890123456';

function encrypt(data, key) {
  const sKey = CryptoJS.enc.Utf8.parse(key);
  const sContent = CryptoJS.enc.Utf8.parse(data);
  const encrypted = CryptoJS.AES.encrypt(sContent, sKey, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7
  })
  return encrypted.toString();
}

function decrypt(data, key) {
  const sKey = CryptoJS.enc.Utf8.parse(key);
  const decrypt = CryptoJS.AES.decrypt(data, sKey, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7
  })
  return CryptoJS.enc.Utf8.stringify(decrypt).toString();
}

const encrypted = encrypt(plaintext, key)

console.log('加密:', encrypted); 

const decrypted = decrypt(encrypted, key)

console.log('解密:', decrypted);           

上述示例代碼輸出結果:

加密: Qo3E1B8ZR6Mry99RJm+h41hl/AFpFd6eczi//vidPdleezANZ+3T3DJsqEx3HhRu
解密: {"objectName":"test","pageNo":0,"pageSize":10}           

Java版本

開發必備:多種語言實作AES加密解密示例保證資料安全傳輸與存儲

在 Java 中,可以使用 javax.crypto 包中的 Cipher 類來實作 AES 加密和解密。

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class AESUtil {
    private static final String AES_ALGORITHM = "AES";
    private static final String AES_TRANSFORMATION = "AES/ECB/PKCS5Padding";
    // 密鑰,使用者自定義
		private static final String AES_KEY = "1234567890123456";

    public static String encrypt(String plaintext) {
        try {
            SecretKeySpec secretKey = new SecretKeySpec(AES_KEY.getBytes(StandardCharsets.UTF_8), AES_ALGORITHM);
            Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String decrypt(String encryptedText) {
        try {
            SecretKeySpec secretKey = new SecretKeySpec(AES_KEY.getBytes(StandardCharsets.UTF_8), AES_ALGORITHM);
            Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) throws Exception {
      	// 明文
        String plaintext = "{\"objectName\":\"test\",\"pageNo\":0,\"pageSize\":10}";
        // AES 加密
        String encryptedText = encrypt(plaintext);
        System.out.println("加密: " + encryptedText);
        // AES 解密
        String decryptedText = decrypt(encryptedText);
        System.out.println("解密: " + decryptedText);
        // 解密前端密文,上述js版本AES加密生成
        String decryptedText2 = "Qo3E1B8ZR6Mry99RJm+h41hl/AFpFd6eczi//vidPdleezANZ+3T3DJsqEx3HhRu";
        System.out.println("解密前端密文: " + decryptedText2);
    }
}           

上述示例代碼輸出結果:

加密: Qo3E1B8ZR6Mry99RJm+h41hl/AFpFd6eczi//vidPdleezANZ+3T3DJsqEx3HhRu
解密: {"objectName":"test","pageNo":0,"pageSize":10}
解密前端密文: {"objectName":"test","pageNo":0,"pageSize":10}           

Python版本

開發必備:多種語言實作AES加密解密示例保證資料安全傳輸與存儲

在 Python 3 中,你可以使用 pycryptodome 庫來進行 AES 算法的 ECB 模式和 PKCS5Padding 填充方式的加密和解密。

安裝了 pycryptodome 庫:

pip install pycryptodome           

示例代碼:

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64

# 密鑰,使用者自定義
key = '1234567890123456';

# 明文
plaintext ='{"objectName":"test","pageNo":0,"pageSize":10}'

# 建立 AES 加密器和解密器
cipher = AES.new(key, AES.MODE_ECB)
decipher = AES.new(key, AES.MODE_ECB)

# 加密
encrypted_text = cipher.encrypt(pad(plaintext.encode('utf-8'), AES.block_size))
encrypted_text_base64 = base64.b64encode(encrypted_text).decode('utf-8')
print('加密後的資料:', encrypted_text_base64)

# 解密
decrypted_text = decipher.decrypt(base64.b64decode(encrypted_text_base64))
decrypted_text = unpad(decrypted_text, AES.block_size).decode('utf-8')
print('解密後的資料:', decrypted_text)           

Node.js版本

開發必備:多種語言實作AES加密解密示例保證資料安全傳輸與存儲

在 Node.js 中,可以使用 crypto 子產品來實作AES 算法的 ECB 模式和 PKCS5Padding 填充方式

const crypto = require('crypto');

function encrypt(text, key) {
  const cipher = crypto.createCipheriv('aes-128-ecb', key, '');
  cipher.setAutoPadding(true);
  let encrypted = cipher.update(text, 'utf8', 'base64');
  encrypted += cipher.final('base64');
  return encrypted;
}

function decrypt(encryptedText, key) {
  const decipher = crypto.createDecipheriv('aes-128-ecb', key, '');
  decipher.setAutoPadding(true);
  let decrypted = decipher.update(encryptedText, 'base64', 'utf8');
  decrypted += decipher.final('utf8');
  return decrypted;
}

// 明文
const plaintext ='{"objectName":"test","pageNo":0,"pageSize":10}'
// 密鑰,使用者自定義
const key = '1234567890123456';

const encrypted = encrypt(plaintext, key)
console.log('加密:', encrypted); 

const decrypted = decrypt(encrypted, key)
console.log('解密:', decrypted);

// 解密前端密文,上述js版本AES加密生成
const decrypted2 = 'Qo3E1B8ZR6Mry99RJm+h41hl/AFpFd6eczi//vidPdleezANZ+3T3DJsqEx3HhRu'
console.log('解密前端密文:', decrypt(decrypted2));
           

歡迎點贊+關注,檢視後續更多精彩内容!!!

繼續閱讀