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

时间:2018-01-22 07:49:30

标签: java aes

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

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

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

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 个答案:

答案 0 :(得分: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);

其中symetric加密本身可以如下实现

// 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);