从证书文件中获取密钥以在 AES 算法中进行加密和解密



我正在进行AES加密,其中我将使用证书文件中的密钥来初始化密码,如下所示。

encryptModeCipher = Cipher.getInstance("AES");
encryptModeCipher.init(Cipher.ENCRYPT_MODE, aesSecretKey);

但是我在这里看到的问题是,对于我使用的所有证书,我的密钥((都保持不变。任何建议为什么?并提出一个好主意。

 byte[] encryptionKey = Arrays.copyOf(encoded, 32);
        secretKey = new SecretKeySpec(encryptionKey, algorithm);

public class AESEncryptionServiceHelper {
    private String algorithm = "AES";
    private String certPass;
    private SecretKey secretKey;
    public SecretKey setKey() {
        try {
            certPass="****";
            char[] pass = certPass.toCharArray();
            KeyStore keyStore = KeyStore.getInstance("jceks");
            
            File file = new File("D:/aws-kms-dps/***.jks");
            InputStream inputStream = new FileInputStream(file);
            keyStore.load(inputStream, pass);
            Certificate cert = keyStore.getCertificate("****");
            Key key = cert.getPublicKey();
            secretKey = new SecretKeySpec(key.getEncoded(), algorithm);
            byte[] encoded = secretKey.getEncoded();
            byte[] encryptionKey = Arrays.copyOf(encoded, 32);
            secretKey = new SecretKeySpec(encryptionKey, algorithm);
        } catch (IOException e) {
            System.out.println(e);
        } catch (Exception e) {
            System.out.println(e);
        }
        return secretKey;
    }
    
    public static void main(String args[]){
        AESEncryptionServiceHelper aesEncryptionServiceHelper=new AESEncryptionServiceHelper();
        aesEncryptionServiceHelper.setKey();
    }
}

您似乎正在使用(部分(公钥作为AES密钥。这是非常糟糕的主意,因为

  • 公钥是..很好..公共和静态
  • 它具有相对较低的熵(因为多个字节以ASN.1格式定义(

您是否做过任何研究如何使用PKI正确进行加密,或者您只是在猜测/使用加密API进行加密?

假设您想使用公钥和AES进行加密(称为混合加密(,您可以从我的博客中举例说明

请阅读并理解(或任何其他关于密码学的好博客(,似乎您缺少使用 IV(盐(和 MAC

 // generate random AES key
 KeyGenerator keyGenerator = KeyGenerator.getInstance(SYMMETRIC_KEY_ALG);
 SecretKey symmetricKey = keyGenerator.generateKey();
 // this assumes there's whole keypair (including private key)
 // normally only a certificate with PubKey is available
 PublicKey pubKey = keystoreEntry.getCertificate().getPublicKey();
 params.setKey(symmetricKey.getEncoded());
 // execute symmetric encryption
 this.symmetricEncryption(params);
 // encrypt the key with the public key
 Cipher cipher = Cipher.getInstance(PKI_CIPHER_ALG);
 cipher.init(Cipher.WRAP_MODE, pubKey);
 byte[] wrappedKey = cipher.wrap(symmetricKey);
 LOGGER.log(Level.INFO, "Wrapped key: {0}", Base64.getEncoder().encodeToString(wrappedKey));
 params.setKey(wrappedKey);

其中对称加密本身可以按如下方式实现

// initialization vector
 SecureRandom rnd = new SecureRandom();
 byte[] iv = new byte[SYMMETRIC_BLOCK_SIZE / 8];
 rnd.nextBytes(iv);
 encryptionParams.setIv(iv);
 IvParameterSpec ivParamSpec = new IvParameterSpec(iv);
 SecretKey symmetricKey = new SecretKeySpec(encryptionParams.getKey(), SYMMETRIC_KEY_ALG);
Cipher cipher = Cipher.getInstance(SYMMETRIC_CIPHER_NAME);
cipher.init(Cipher.ENCRYPT_MODE, symmetricKey, ivParamSpec);
 // for HMAC we should be able to use the same key as for encryption
 // for CBC-MAC it may not be the case
 // https://en.wikipedia.org/wiki/CBC-MAC#Using_the_same_key_for_encryption_and_authentication
 Mac mac = Mac.getInstance(EncryptionTest.HASH_ALGORITHM_NAME);
 mac.init(symmetricKey);
 byte[] encrypted = cipher.doFinal(encryptionParams.getPlaintext());
 encryptionParams.setCiphertext(encrypted);
 byte[] authTag = mac.doFinal(encrypted);
 encryptionParams.setMac(authTag);

最新更新