Code Examples – Signing a message

Introduction  |  Message Digest  |  Symmetric ciphers  |  RSA  |  ECIES  |  Digital signatures (S/MIME)

Download code

Signing a message: The purpose of this code example is to show how to sign a message using certificates in combination with the RSA public key algorithm. In the first part of the code we will acquire a valid private key from a PKCS#12-file and then we will use this key for signing the message with the FlexiProvider implementations.

First, we do the necessary imports:

01 import java.io.File;
02 import java.io.FileInputStream;
03 import java.io.FileOutputStream;
04 import java.security.PrivateKey;
05 import java.security.Security;
06 import java.security.Signature;
07
08 import codec.asn1.DERDecoder;
09 import codec.pkcs12.PFX;
10 import codec.pkcs12.PKCS8ShroudedKeyBag;
11 import codec.pkcs12.SafeBag;
12 import de.flexiprovider.core.FlexiCoreProvider;
13
14 public class ExampleSMIMESignRSA {
15
16 public static void main(String[] args) throws Exception {
17
18 Security.addProvider(new FlexiCoreProvider());

Next, we have to read the private PKCS #12 file, since the the private key used for signing is contained in this file:

20 DERDecoder dec = new DERDecoder(new FileInputStream("CertRSA.p12"));
21 PFX pfx = new PFX();
22 pfx.decode(dec);

In line 20, we wrap a FileInputstream pointing to the file on the local disk into a DERDecoder instance. The DERDecoder is a FilterInputstream which is used to read ASN.1/DER encoded types. In lines 21 and 22, we use a PFX instance to decode the structure. A PFX instance represents a PFX as defined in the PKCS #12 standard.

Now we can extract the private key from the PKCS #12 file. Since it is protected with a password, we must provide a valid password for accessing the private key:

24 SafeBag safeBag = pfx.getAuthSafe().getSafeContents(0).getSafeBag(0);
25 PKCS8ShroudedKeyBag kBag = (PKCS8ShroudedKeyBag) safeBag.getBagValue();
26
27 char[] password = "certRSA".toCharArray();
28 PrivateKey privKey = kBag.getPrivateKey(password);

In line 24, we call 3 functions on the previously instantiated PFX to get the SafeBag from the PKCS #12 file:

  • getAuthSafe(): returns an AuthenticatedSafe as defined in the PKCS #12 standard
  • getSafeContents(int i): returns the SafeContents (which in turn contains a SafeBag)
  • getSafeBag(int i): returns the actual SafeBag

The SafeBag itself contains an ASN1Type representing the bag value (=encrypted key). This value is stored in a PKCS8ShroudedKeyBag instance which can hold one private key. In line 28, we finally get the private key by using the bag's getPrivateKey(char[] password) method providing the password protecting the private key in the structure. This hierarchical structure is defined in the PKCS #12 standard (for a deeper understanding please refer to the standard's documentation).

Now we are ready to create a signature for a file using the acquired key. We load the file from the local disc:

30 File file = new File("MyEmail");
31 byte[] buffer = new byte[(int) file.length()];
32 FileInputStream fis = new FileInputStream(file);
33 fis.read(buffer);
34 fis.close();

Next, we create a Signature object which is then used to generate a signature for the file:

36 Signature sig = Signature.getInstance("SHA1withRSA", "FlexiCore");
37
38 sig.initSign(privKey);
39 sig.update(buffer);
40 byte[] sigBytes = sig.sign();

In line 36, we use the static getInstance(String algorithm, Provider provider) method to create a signature object that implements the specified algorithm. The call of initSign(PrivateKey privateKey) in line 38 initializes the object for signing messages with the given private key. Next, the content to be signed is read with the update(byte[] data)-method (which could be called several times) and finally the signature is generated in line 40 via the sign()-method. This method returns the signature for all the data contained in the signature object as byte array and afterwards resets the object, so that it can be used again for signing other messages.

What is left to do now is to write the signature to a file:

42 FileOutputStream fos = new FileOutputStream("RSASignature.sig");
43 fos.write(sigBytes);
44 fos.close();
45 }
46
47 }

The signature can now be sent along with the message and verified by the recipient in combination with the user's public certificate. For the process of verifying digital signatures please look at the code example for verifying digital signatures.

Druckerenglisch deutsche Flagge   Impressum