java - 从证书文件中获取 key 用于 AES 算法加密和解密

标签 java aes

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

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

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

byte[] cryptoKey = Arrays.copyOf(encoded, 32); SecretKey = new SecretKeySpec(加密 key , 算法);

公共(public)类 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 key 。这是非常糟糕的主意

  • 公钥是..嗯..公开且静态的
  • 它具有相对较低的熵(因为 ASN.1 格式中定义了多个字节)

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

假设您想使用公钥和 AES 进行加密(称为 hybrid encryption ),您可以以 my blog 为例。

请阅读并理解(或任何其他有关密码学的好博客),似乎您缺少使用 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);

关于java - 从证书文件中获取 key 用于 AES 算法加密和解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48376813/

相关文章:

java - 在 JFrame 中设置文本格式

c++ - 如何使用 cryptoAPI 进行 AES CBC 加密

c - OpenSSL 和 AES

C# AES 256 位解密给定的加密文本和 secret

java - 如何在 Java 中为文件名(不是内容)指定一个字符集?

java - 如何修改/适配 API 库中的方法?

java - 从装有 Apache Tomcat 8.x 的 Linux 服务器使用 Java Web App 打开 Outlook

java - 如何使用 Dagger 2 注入(inject) pojo 依赖项?

java - 在 Java 和 PHP 之间加密/解密字符串

PHP AES 加密/解密