Self-signed certificate with CA
I am working on a solution for file encryption via a combination of RSA and AES. RSA is basically used here for a handshake to encrypt a symmetric key and decrypt with the key pair at the receiver side.
I have used Java keystore for private key and self signed certificate for public key. Both are created as follows:
key store
keytool -genkey -keyalg RSA -alias BANK -keystore receiverKeystore.jks -validity 360 -keysize 2048
Certificate export
keytool -export -alias BANK -keystore receiverKeystore.jks -rfc -file bankCert.cer
Again, both are used in Java as follows:
private key
private void setKeys() {
KeyStore senderKeyStore = null;
String keyStorePassword = "fms123";
try {
senderKeyStore = KeyStore.getInstance( "JKS" );
FileInputStream is = new FileInputStream( keystorePath );
senderKeyStore.load( is, keyStorePassword.toCharArray() );
senderPrivateKey = ( PrivateKey ) senderKeyStore.getKey( KEYSTORE_ALIAS, keyStorePassword.toCharArray() );
receiverPublicKey = loadReceiverPublicKeyFromCertificate();
}
catch ( Exception e ) {
System.out.println( " Exception in setting keys from key store = " + e );
}
}
public key
private PublicKey loadReceiverPublicKeyFromCertificate () {
PublicKey publicKey = null;
try {
FileInputStream fin = new FileInputStream( certificateFilePath );
CertificateFactory factory = CertificateFactory.getInstance( "X.509" );
X509Certificate certificate = ( X509Certificate ) factory.generateCertificate( fin );
publicKey = certificate.getPublicKey();
}
catch ( Exception e ) {
System.out.println( " Exception in loading receiver certificate = " + e );
}
return publicKey;
}
I now have the following questions:
- Is it the right way?
If I use a trusted certificate here, how will I get the public key from it? Will it be fetched the same way? and private key? Will I use the same method or something from the certificate?
How to distribute certificates to recipients? For this, what is the use of secure communication?
I'm new to cryptography and would love to get some advice.
Your handshake is called key establishment . Handshake is used in (online) transport mode, but I don't think you developed that. I would use PKCS#12 keystore instead, JKS is a bit outdated. The whole idea of using a char[]
as a password is that its contents can be deleted directly after using a, so using String
as as an input is not a good idea. Strings are usually detained and immutable in Java, so you can't destroy them without ugly hacks involving native code.
A trusted certificate is no different from an untrusted certificate. Yes, you can retrieve the public key from it. The private key is usually stored with the certificate chain leading to the leaf user certificate to which the private key belongs. However, the private key is not part of the certificate , so you cannot retrieve the private key from the certificate. It doesn't matter, the private key should be established where the private key is required. There is no need to transfer them except for backup purposes.
How you send the certificate to the recipient is up to you. The tricky part is getting the recipient to trust the certificate. Using pre-established keys (such as trusted PGP keys) works. If you don't have such a key, you're in trouble. What you can do is build trust using other methods. It's probably one of the easiest ways to have the other party call you and then verify that the certificate thumbprint (basically just the hash on the certificate) is correct. If your users aren't too far from us, you can of course bring them in person as well.
However, you cannot create secure channels out of thin air. If you don't trust the other person, it's obviously impossible to establish complete trust.