0
votes

I am doing a AES encryption , in which i will use a secret key from cert file as below to initialise the cipher.

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

But the problem i see here is that, my secretKey () remains the same for all the certificates that i use. Any suuggestion why? and suggest a good idea to do so.

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();
}

}

1
There is no secret key in a certificate file. Everything in it is public, by definition, including the public key from which you are constructing your so-called 'secret key', by definition. If you're using a public key as a secret key you are already engaged in complete and utter insecurity. Unclear what you're asking, or what you're even talking about.user207421
Yes. I am little unclear on this ... I can only get a public key from the certificate ... but somehow I need to generate a Secret key from it.. suggest me a good waysundar
No, you don't need to do that, because it is insecure. You don't need to do wrong things. Possibly you have misunderstood your requirement. Send it back for clarification.user207421

1 Answers

2
votes

You seems you are usging (part of) the public key as an AES key. That is VERY BAD idea as

  • the public key is .. well .. public and static
  • it has relatively low entropy (as multiple bytes are defined in the ASN.1 format)

Did you do any research how to properly do encryption using PKI or you are just guessing / plaing with the crypto API?

Let's assume you want to do encryption using the public key and AES (it is called hybrid encryption), you could take example from my blog

Please read it and understand (or any other good blogs about cryptography), seems you are missing using IV (salt) and 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);

where the symetric encryption itself can be implemented as follows

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