从 cert 文件中获取 Secret Key 以用于 AES 算法进行加密和解密

Posted

技术标签:

【中文标题】从 cert 文件中获取 Secret Key 以用于 AES 算法进行加密和解密【英文标题】:Obtaining Secret Key from cert file to use in AES algorithm for encryption and decryption 【发布时间】:2018-06-30 19:15:54 【问题描述】:

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

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

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

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

公共类 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();

【问题讨论】:

证书文件中没有密钥。根据定义,其中的所有内容都是公开的,包括您从中构建所谓的“秘密密钥”的公钥。如果您使用公钥作为密钥,那么您已经处于完全不安全的状态。不清楚你在问什么,甚至在说什么。 是的。我对此不太清楚......我只能从证书中获取一个公钥......但不知何故我需要从中生成一个秘密密钥......建议我一个好方法 不,您不需要这样做,因为它不安全。你不需要做错事。可能你误解了你的要求。发回以澄清。 【参考方案1】:

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

公钥是 .. 好 .. 公开的和静态的 它的熵相对较低(因为在 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);

【讨论】:

以上是关于从 cert 文件中获取 Secret Key 以用于 AES 算法进行加密和解密的主要内容,如果未能解决你的问题,请参考以下文章

带有 laravel 的 Paypal sdk - 从 env 文件中获取 Client_id/secret

使用stringIO对象作为ssl key / cert文件

如何解决 Secret tls-cert.default 未知问题?

从带有前缀的 Azure Key Vault 获取所有机密

使用 Azure Key Vault 进行 Terraform 以获取机密值

其他应用程序是不是可以从 Django settings.py 中读取 SECRET KEY?