簡體   English   中英

Python 和 java AES/ECB/PKCS5 加密

[英]Python and java AES/ECB/PKCS5 encryption

JAVA 版本:

public class EncryptUtil {
    public static String AESEncode(String encodeRules, String content) {
        try {
            KeyGenerator keygen = KeyGenerator.getInstance("AES");
            keygen.init(128, new SecureRandom(encodeRules.getBytes()));
        SecretKey original_key = keygen.generateKey();
        byte[] raw = original_key.getEncoded();
        SecretKey key = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] byte_encode = content.getBytes("utf-8");
        byte[] byte_AES = cipher.doFinal(byte_encode);
        return new String(Base64.getEncoder().encode(byte_AES));
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
       return null;
   }

}

當我運行此代碼時:

System.out.println(EncryptUtil.AESEncode("1234567812345678", python&java"));

我有:

V5FFUgDi7VZaJ0qGzDISoA==

PYTHON 版本:

import base64

from Crypto.Cipher import AES

BLOCK_SIZE = 16  # Bytes
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * \
            chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]


class AESUtil:
    __BLOCK_SIZE_16 = BLOCK_SIZE_16 = AES.block_size

    def __init__(self, key):
         self.key = key

    def encrypt(self, raw):
        raw = pad(raw)
        cipher = AES.new(self.key, AES.MODE_ECB)
        return base64.b64encode(cipher.encrypt(raw))

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        cipher = AES.new(self.key, AES.MODE_ECB)
        return unpad(cipher.decrypt(enc))

我知道 java 默認使用 AES/ECB/PKCS#5,但是當我運行encrypt方法時:

cipher_text = AESUtil("1234567812345678").encryt('python&java')

得到: b'3mjygpK1d7ThCRK98ssZhA=='

我在 Google 中找到了 pad 和 unpad。 如何編輯我的 PYTHON 代碼使 cipher_text 等於 JAVA 加密。 有人可以知道如何解決嗎?

您使用不同的加密密鑰

在Java中

System.out.println(EncryptUtil.AESEncode(“ 1234567812345678”,“ python&java”));

看代碼:

KeyGenerator keygen = KeyGenerator.getInstance("AES");
keygen.init(128, new SecureRandom(encodeRules.getBytes()));
SecretKey original_key = keygen.generateKey();
byte[] raw = original_key.getEncoded();

如果打印raw密鑰,則會得到fd839759956ba4a47922e8ee7c902f52 (十六進制編碼),這是加密密鑰

如果您想直接使用提供的密鑰,則應使用

byte[] raw = encodeRules.getBytes(); 
// (assuming encodeRules has 16 bytes)

如何編輯我的PYTHON代碼,使cipher_text等於JAVA加密

這很棘手..您可能會看到SecureRandom的工作原理 ,但是恕我直言,修復Java實現以創建您期望的密鑰更容易

無論如何,我都認為實施不夠安全-使用ECB和簡單密鑰。

檢查此實用程序 - https://github.com/EverWinter23/aes-ecb-pkcs5 它使用 python 標准庫,用於具有可變大小密鑰的 AES/ECB/PKCS5 密碼——嘗試使用 key_size=BLOCK_SIZE。


import hashlib
from base64 import b64decode as b64D
from base64 import b64encode as b64E

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes

UTF_8 = "utf-8"


def make_aes_ecb_cipher(secret: str, key_size: int = 16) -> 
    return Cipher(
        algorithms.AES(make_key(secret, key_size)),
        modes.ECB(),
        backend=default_backend(),
    )


def make_key(secret: str, key_size: int) -> str:
    if key_size <= 0:
        AssertionError("key_size cannot be <=0.")
    return hashlib.sha256(secret.encode(UTF_8)).digest()[:key_size]


def encrypt_to_base64(plain_text: str, secret: str, key_size: int) -> str:
    padder = padding.PKCS7(algorithms.AES.block_size).padder()
    padded_bytes = padder.update(plain_text.encode(UTF_8)) + padder.finalize()
    cipher = make_aes_ecb_cipher(secret, key_size)
    encryptor = cipher.encryptor()
    encrypted_bytes = encryptor.update(padded_bytes) + encryptor.finalize()
    return b64E(encrypted_bytes).decode(UTF_8)


def decrypt_from_base64(encrypted_text: str, secret: str, key_size: int) -> str:
    encrypted_bytes = b64D(encrypted_text)
    cipher = make_aes_ecb_cipher(secret, key_size)
    decryptor = cipher.decryptor()
    padded_bytes = decryptor.update(encrypted_bytes) + decryptor.finalize()
    unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
    unpadded_bytes = unpadder.update(padded_bytes) + unpadder.finalize()
    return unpadded_bytes.decode(UTF_8)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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