我正在进行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);