Most Read This Week
Java Cryptography | Part 3
Decryption and verifying signatures
By: James H. Wong
Feb. 22, 2013 12:00 PM
After you have secured your private electronic information using encryption and learned how to encrypt and digitally sign files for others, how do you extract the information and determine who encrypted the file? Asymmetric public/private key encryption allows you to decipher the information and verify the accompanying digital signature if it exists.
This article illustrates how to decrypt and verify the digital signature on files encrypted using a hybrid combination of asymmetric public/private key encryption and symmetric encryption. A symmetric key is used to encrypt the file and the asymmetric public key encrypts the symmetric key. The asymmetric private key decrypts the symmetric key which in turn is used to decrypt the encrypted file.
Figure1: Asymmetric Key Encryption Functions
The same pair of keys can be used with digital signatures. The private key is used to sign a file and generate a digital signature. The public key is used to verify the authenticity of the signature.
Figure 2: Asymmetric Key Signature Functions
The decryption technique requires the Java libraries developed by the Legion of the Bouncy Castle (www.bouncycastle.org). The Bouncy Castle jars, bcprov-jdk15on-147.jar and bcpkix-jdk15on-147.jar, contains all the methods required to encrypt, decrypt, sign and verify a digital signature. The following Java code snippet loads the BouncyCastle provider, which implements the Java Cryptography Security services such as algorithms and key generation.
Decryption for Files or Java Objects
Step 1: Assume you want to decrypt the encrypted file, C:\sampleFile.txt.jxdoe_nnnn.asg and the String variable, tUniqueAlias = "jxdoe_nnnn", holds the alias associated to the encrypted file. Read the header from the encrypted file and determine decrypted output name.
File tSrcFile = new File("C:\\sampleFile.txt." + tUniqueAlias + ".aes");
Step 2: The private key is stored in a Java key store and is password protected. Load the key store using your password. Retrieve the asymmetric private key from the key store using the same password. The asymmetric private key will be used to decrypt the symmetric key.
FileInputStream tFIStream = new FileInputStream("C:\\jxdoe_nnnn.jks");
Figure 3: Private Key
Step 3: Generate a Java Cipher object using the asymmetric private key and set its mode to "Cipher.UNWRAP_MODE".
Cipher tCipherRSA = Cipher.getInstance("RSA", "BC");
Step 4: Use the Java Cipher and asymmetric private key to unwrap the symmetric key. It's located in the header at the instance variable, wrappedSymKey or wrappedSymKeyOther, along with symmetric algorithm at symKeyAlgDesc. The symmetric key will be used to decrypt the file.
String tAlg = tHead.symKeyAlgDesc();
Figure 4: Unwrap Symmetric Key
Step 5: Re-initialize the same Cipher to Cipher.DECRYPT_MODE. Use the Cipher and the asymmetric private key to decrypt the initialization vector stored within the header at the instance variable initVector or initVectorOther.
Figure 5: Unwrap Initialization Vector
Step 6: Generate a Java Cipher object using the symmetric key and initialization vector and set its mode to "Cipher.DECRYPT_MODE". The string representing the symmetric algorithm, mode and padding can be extracted from the Cryptography header using the "transformation" method.
tCipherDecrypt = Cipher.getInstance("AES/CTR/PKCS7Padding", "BC");
Step 7: Use the Java Cipher to decrypt the rest of the file to a Java FileOutputStream. The DataInputStream points to the start of the encrypted data after reading the header. The end result is a decrypted file.
byte tInBuffer = new byte;
Figure 6: Decipher the Encrypted File
Step 7a: If the encrypted file contains a Java object, use the Java Cipher to decrypt the rest of the file to a Java ByteArrayOutputStream instead of a FileOutputStream. The end result can be converted to an instance of its original Java class.
ByteArrayInputStream tBAIS = new ByteArrayInputStream(tBAOS.toByteArray());
Alternatively, the same technique can be used to decrypt the encrypted file using the symmetric key that was wrapped with the CA or owner's asymmetric public key. If the file was encrypted for another user, the owner can decrypt it using the additionally wrapped symmetric key. If the file was encrypted for oneself, the CA can decrypt it using the additionally wrapped symmetric key in the enterprise version.
Step 1: Assume you want to verify the signature on the encrypted and digitally signed file, "C:\sampleFile.txt.jxdoe_nnnn.asg" and the String variable, tUniqueAlias = "jxdoe_nnnn", holds the alias associated to the file. Read the header from the signed file. After the header is read, keep in mind that the DataInputStream now points to the beginning of the encrypted data.
File tSrcFile = new File("C:\\sampleFile.txt." + tUniqueAlias + ".asg");
Step 2: Retrieve the certificate whose name is stored in the header and contains the asymmetric public key needed for verification. Retrieve the asymmetric public key from the certificate associated with the digital signature.
String tCertName = "C:\\" + tHead.verifySigCertName();
Figure 7: Extract Public Key
Step 3: Instantiate a Java signature engine and initialize it with the signature algorithm stored in the header and the asymmetric public key. The default value is "SHA512WithRSAEncryption".
Signature tSgnVerifyEngine = null;
Step 4: Use the Java signature engine to process the rest of the signed file and calculate a hash number that will be compared with the signature stored in the header.
int tBlockSize = 4096;
Step 5: After the file has been processed, use the Java signature engine to verify its result with the digital signature. A Boolean result is returned on whether the signature was valid.
Boolean tResult = tSgnVerifyEngine.verify(tCurrSignature);
The source code (LaCryptoJarSample.java) is available on the Logical Answers Inc. website under the education web page as an individual file and also within the zip file, laCrypto-4.2.0.zipx.
References and Other Technical Notes
Reader Feedback: Page 1 of 1
Subscribe to the World's Most Powerful Newsletters
Today's Top Reads