Jasypt StandardPBEStringEncryptor setting password in spring bean configuration file - security

When using Jasypt's StandardPBEStringEncryptor we have to set password explicitly in spring bean configuration file. Is it ok and secure to have the password in the bean configuration file? Will it be a problem in PCI Compliance to store the encryptor password?

This will not be PCI compliant. Data encrypting keys cannot be stored in plaintext. The specific point is 3.5.2 which is:
Examine system configuration files to
verify that keys are stored in
encrypted format, and that
key-encrypting keys are stored
separately from data-encrypting keys.
You would probably also have other issues around the key management area, such as 3.6.6 (Split knowledge and dual control of keys)
Verify that key-management procedures
are implemented to require split
knowledge and dual control of keys
(for example, requiring two or three
people, each knowing only their own
part of the key, to reconstruct the
whole key).
Key management is the most challenging part of PCI compliance. You may want to consider using a (already PCI compliant) 3rd party to manage your card data. If you are rolling your own then I would advise that you bring in the assistance of a QSA (PCI Qualified Security Assesor) at the earliest opportunity to evaluate the security you're planning on implementing. ultimately it will be the QSA that you need to convince in order to pass your PCI requirements, and they will be more than happy to advise.

You need to store the symmetric key somewhere. A configuration file is a good place, as long as no one has access to it.

I have an idea
you can encrypt all of your plain password with keyPair of keystore.jks. You know that the keystore.jks has its own password. you can remember that password and when your program get started enter it on console. for example when your program start:
Console console = System.console();
keyPair = loadKeystore(new String(console.readPassword()));
private static KeyPair loadKeystore(String pwd) {
InputStream is = Main.class.getResourceAsStream("/keystore.jks");
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(is, s.toCharArray());
String alias = "youralias";
Key key = keystore.getKey(alias, pwd.toCharArray());
if (key instanceof PrivateKey) {
// Get certificate of public key
Certificate cert = keystore.getCertificate(alias);
// Get public key
PublicKey publicKey = cert.getPublicKey();
// Return a key pair
return new KeyPair(publicKey, (PrivateKey) key);
}
return null;
}
when you return the keypair you can uses it for encrypt your password.
key = loadKeystore("yourpass").getPrivate().getEncoded()
goodluck

Related

Use aws-encryption-sdk to decrypt with context in on-prem environment

I want to consume encrypted messages using the aws_encryption_sdk python module. The messages are encrypted by another team using a context.
The reason to use aws_encryption_sdk is to reduce the cost by reducing the number of KMS sessions whenever we call the boto3 kms client decrypt function. However, I seem to be stuck and confused as I can't find where I can use that when calling the decrypt function for the EncryptionSDKClient
My code looks something like this:
client = aws_encryption_sdk.EncryptionSDKClient()
## try to set the botocore session for Master Key Provider
kms_kwargs= dict(key_ids=data['keyId'])
key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(**kms_kwargs)
MAX_ENTRY_AGE_SECONDS = 600.0
MAX_ENTRY_MESSAGES = 10
MAX_CACHE_SIZE = 10
cache = aws_encryption_sdk.LocalCryptoMaterialsCache(MAX_CACHE_SIZE)
caching_cmm = CachingCryptoMaterialsManager(
master_key_provider=key_provider,
cache=cache,
max_age=MAX_ENTRY_AGE_SECONDS,
max_messages_encrypted=MAX_ENTRY_MESSAGES
)
cycled_plaintext, decrypted_header = client.decrypt(source=base64.b64decode(data["encryptedData"]), key_provider=key_provider)
Please note that I need to cache the data key in on-premise environment.
From the AWS Developer Guide on KMS Encryption SDK page, encryption context section:
To decrypt the data, you pass in the encrypted message. Because the AWS Encryption SDK can extract the encryption context from the encrypted message header, you are not required to provide the encryption context separately. However, the encryption context can help you to confirm that you are decrypting the correct encrypted message.
There is also a few examples of code verifying the encryption contexts that you may find useful here.

Storing encrypted PrivateKey's to Java Keystores

Java Keystores (e.g. JKS, PKCS) allow saving private keys (interface
Key) and
certificate chains. However a RSA KeyPair's private key which is encrypted
(e.g. EncryptedPrivateKeyInfo in bouncycastle or in javax) does not implement
Key interface.
What is the correct way to store encrypted private keys in a keystore?
If you already have an EncryptedPrivateKeyInfo, you should be able to use that directly when creating the keystore entry. Java stores the PrivateKey in the KeyStore as EncryptedPrivateKeyInfo format.
You need to use this method in the KeyStore.setKeyEntry(String alias, byte[] key, Certificate[] chain). Documentation here.
The other setKeyEntry method takes in an addtional argument, which is the password, which the Java will construct the EncryptedPrivateKeyInfo itself with the password provided.
Note: Only if the Key Protection Algorithm is supported by Java, it will import the private key, or else it will complain. If it does complain, you can look at other option of decrypting the encrypted private key yourself, and using the other setKeyEntry() method.

Require key file by path in Google Cloud Function

I have the functions for Google Cloud Function that needs to require json key file.
For example:
const SERVICE_ACCOUNT_EMAIL = 'your_service_account_email#developer.gserviceaccount.com';
const SERVICE_ACCOUNT_KEY_FILE = require('./path/to/your/service_account.json');
const jwtClient = new google.auth.JWT(
SERVICE_ACCOUNT_EMAIL,
null,
SERVICE_ACCOUNT_KEY_FILE.private_key,
['https://www.googleapis.com/auth/androidpublisher'],
null
);
How I can get access for SERVICE_ACCOUNT_KEY_FILE? Where should I upload the file and how next do I will find its path?
This is a key from the private/public key pair that you create. It will be wrapped inside a JSON (at least that is the common usage). See examples here and documentation here. Never share your private key, but you can freely share your public key (in fact it is required that you share your public key). And don't put your private key into a source control (git repo).
You can find a lot of good information about asymmetric asymmetric cryptography (public key cryptography) online.
In case you are wondering where to add the key file, it should be here: https://www.npmjs.com/package/google-oauth-jwt#creating-a-service-account-using-the-google-developers-console
UPDATE:
Where should you add the file to be able to access it:
One of the best practice is to put the file in a bucket, to allow the function service account (the default one or a specific identity) to read this bucket and to load the file at runtime. One of the main reason is that you don't have to commit your security file, you just have to keep a reference to a bucket.
Reference

Keystore from digital signature e-token using java

How to create the keystore from digital signature e-token? How crate the path of keystore? How to sign with the keystore in any document using java application?
Cryptographic hardware devices can usually be interfaced via PKCS#11 API. You will need PKCS#11 library (.dll on Windows or .so on Unix) acting as a "device driver" which gets usually installed along with the software provided by the device vendor (consult your e-token documentation for the exact library location). You have mentioned "keystore" in your question therefore I guess you are using JAVA language and you can use SunPKCS11 provider to access PKCS#11 compatible cryptographic store. Here is the quick sample:
// Create instance of SunPKCS11 provider
String pkcs11Config = "name=eToken\nlibrary=C:\\path\\to\\your\\pkcs11.dll";
java.io.ByteArrayInputStream pkcs11ConfigStream = new java.io.ByteArrayInputStream(pkcs11Config.getBytes());
sun.security.pkcs11.SunPKCS11 providerPKCS11 = new sun.security.pkcs11.SunPKCS11(pkcs11ConfigStream);
java.security.Security.addProvider(providerPKCS11);
// Get provider KeyStore and login with PIN
String pin = "11111111";
java.security.KeyStore keyStore = java.security.KeyStore.getInstance("PKCS11", providerPKCS11);
keyStore.load(null, pin.toCharArray());
// Enumerate items (certificates and private keys) in the KeyStore
java.util.Enumeration<String> aliases = keyStore.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
System.out.println(alias);
}

Public encryption in crypto on node 0.12

I need to encrypt (and decrypt) a string with a public key previously generated in nodejs (i'm using version 0.12) with crypto module, but i'm unable to do it.
For first i generated the keys in this way:
var diffHell = crypto.createDiffieHellman(60);
diffHell.generateKeys('base64');
var publicKey = diffHell.getPublicKey('base64'); //or whatever 'hex','binary'
var privateKey = diffHell.getPrivateKey('base64'); //or whatever 'hex','binary'
Then i tried to encrypt a string using the generated public key:
crypto.publicEncrypt({key: publicKey}, new Buffer(textToEncrypt));
Running this snippet, node throw this error:
Error: error:0906D06C:PEM routines:PEM_read_bio:no start line
at Error (native)
at Object.exports.publicEncrypt (crypto.js:362:18)
[...]
Reading it, I understand that the key must be in PEM format, but i can't find in the documentation how to tranform a public key in PEM.
So, How i can do that? Someone has done this yet?
Diffie-Hellman (Key Exchange) is an algorithm and protocol to derive a shared secret based on modular arithmetic. It is not a public-key cipher in the same way as RSA is. You cannot use Diffie-Hellman for crypto.publicEncrypt().
Node.js' Crypto module doesn't provide a way to generate a public-private RSA key pair, so you either need to use OpenSSL through child_process or use one of the many modules which provide this sort of thing (e.g. ursa).
You do not need to uses ursa for key generation. Instead you can generate keys with openssl then store the generated PEM keys on your server and try to load them in your script

Resources