Digital signatures - chapter 1

This is a code example of iText PDF, discover more.

1st November 2015
admin-marketing

Switch code for this example

C1_01_DigestDefault.java
/*
 * This class is part of the white paper entitled
 * "Digital Signatures for PDF documents"
 * written by Bruno Lowagie
 * 
 * For more info, go to: http://itextpdf.com/learn
 */
package signatures.chapter1;

import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.Arrays;

public class C1_01_DigestDefault {

	protected byte[] digest;
	protected MessageDigest md;
	
	protected C1_01_DigestDefault(String password, String algorithm, String provider) throws GeneralSecurityException {
		if (provider == null)
			md = MessageDigest.getInstance(algorithm);
		else
			md = MessageDigest.getInstance(algorithm, provider);
		digest = md.digest(password.getBytes());
	}
	
	public static C1_01_DigestDefault getInstance(String password, String algorithm) throws GeneralSecurityException {
		return new C1_01_DigestDefault(password, algorithm, null);
	}
	
	public int getDigestSize() {
		return digest.length;
	}
	
	public String getDigestAsHexString() {
	    return new BigInteger(1, digest).toString(16);
	}

	
	public boolean checkPassword(String password) {
		return Arrays.equals(digest, md.digest(password.getBytes()));
	}
	
	public static void showTest(String algorithm) {
		try {
			C1_01_DigestDefault app = getInstance("password", algorithm);
			System.out.println("Digest using " + algorithm + ": " + app.getDigestSize());
			System.out.println("Digest: " + app.getDigestAsHexString());
			System.out.println("Is the password 'password'? " + app.checkPassword("password"));
			System.out.println("Is the password 'secret'? " + app.checkPassword("secret"));
		} catch (GeneralSecurityException e) {
			System.out.println(e.getMessage());
		}
	}
	
	public static void testAll() {
		showTest("MD5");
		showTest("SHA-1");
		showTest("SHA-224");
		showTest("SHA-256");
		showTest("SHA-384");
		showTest("SHA-512");
		showTest("RIPEMD128");
		showTest("RIPEMD160");
		showTest("RIPEMD256");
	}
	
	public static void main(String[] args) {
		testAll();
	}
}
C1_02_DigestBC.java
/*
 * This class is part of the white paper entitled
 * "Digital Signatures for PDF documents"
 * written by Bruno Lowagie
 * 
 * For more info, go to: http://itextpdf.com/learn
 */
package signatures.chapter1;

import java.security.GeneralSecurityException;
import java.security.Security;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class C1_02_DigestBC extends C1_01_DigestDefault {

	public static final BouncyCastleProvider PROVIDER = new BouncyCastleProvider();
	static {
		Security.addProvider(PROVIDER);
	}
	
	protected C1_02_DigestBC(String password, String algorithm)
			throws GeneralSecurityException {
		super(password, algorithm, PROVIDER.getName());
	}
	
	public static C1_01_DigestDefault getInstance(String password, String algorithm) throws GeneralSecurityException {
		return new C1_02_DigestBC(password, algorithm);
	}

	public static void main(String[] args) {
		testAll();
	}
}
C1_03_EncryptDecrypt.java
/*
 * This class is part of the white paper entitled
 * "Digital Signatures for PDF documents"
 * written by Bruno Lowagie
 * 
 * For more info, go to: http://itextpdf.com/learn
 */
package signatures.chapter1;

import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.X509Certificate;

import javax.crypto.Cipher;

public class C1_03_EncryptDecrypt {

	protected KeyStore ks;
	
	public C1_03_EncryptDecrypt(String keystore, String ks_pass) throws GeneralSecurityException, IOException {
		initKeyStore(keystore, ks_pass);
	}
	
	public void initKeyStore(String keystore, String ks_pass) throws GeneralSecurityException, IOException {
		ks = KeyStore.getInstance(KeyStore.getDefaultType());
		ks.load(new FileInputStream(keystore), ks_pass.toCharArray());
	}
	
	public X509Certificate getCertificate(String alias) throws KeyStoreException {
		return (X509Certificate) ks.getCertificate(alias);
	}
	
	public Key getPublicKey(String alias) throws GeneralSecurityException, IOException {
		return getCertificate(alias).getPublicKey();
	}
	
	public Key getPrivateKey(String alias, String pk_pass) throws GeneralSecurityException, IOException {
		return ks.getKey(alias, pk_pass.toCharArray());
	}
	
	public byte[] encrypt(Key key, String message) throws GeneralSecurityException {
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, key);
		byte[] cipherData = cipher.doFinal(message.getBytes());
		return cipherData;
	}
	
	public String decrypt(Key key, byte[] message) throws GeneralSecurityException {
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, key);
		byte[] cipherData = cipher.doFinal(message);
		return new String(cipherData);
	}
	
	public static void main(String[] args) throws GeneralSecurityException, IOException {
		C1_03_EncryptDecrypt app = new C1_03_EncryptDecrypt("src/main/resources/ks", "password");
		Key publicKey = app.getPublicKey("demo");
		Key privateKey = app.getPrivateKey("demo", "password");
		
		System.out.println("Let's encrypt 'secret message' with a public key");
		byte[] encrypted = app.encrypt(publicKey, "secret message");
		System.out.println("Encrypted message: " + new BigInteger(1, encrypted).toString(16));
		System.out.println("Let's decrypt it with the corresponding private key");
		String decrypted = app.decrypt(privateKey, encrypted);
		System.out.println(decrypted);
		
		System.out.println("You can also encrypt the message with a private key");
		encrypted = app.encrypt(privateKey, "secret message");
		System.out.println("Encrypted message: " + new BigInteger(1, encrypted).toString(16));
		System.out.println("Now you need the public key to decrypt it");
		decrypted = app.decrypt(publicKey, encrypted);
		System.out.println(decrypted);
	}
	
}
C1_01_DigestDefault.cs
/*
 * This class is part of the white paper entitled
 * "Digital Signatures for PDF documents"
 * written by Bruno Lowagie
 * 
 * For more info, go to: http://itextpdf.com/learn
 */

using System;
using System.Security.Cryptography;
using System.Text;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;

namespace signatures.chapter1
{
    public class C1_01_DigestDefault
    {
        protected byte[] digest;
        protected HashAlgorithm hash = null;
    	
	    protected C1_01_DigestDefault(String password, String algorithm) {
	        switch (algorithm) {
                case "MD5":
                    hash = new MD5CryptoServiceProvider();
	                break;
	            case "SHA-1":
                    hash = new SHA1Managed();
                    break;
                case "SHA-256":
                    hash = new SHA256Managed();
                    break;
                case "SHA-384":
                    hash = new SHA384Managed();
                    break;
                case "SHA-512":
                    hash = new SHA512Managed();
                    break;
                case "RIPEMD160":
                    hash = new RIPEMD160Managed();
                    break;
            }
	        digest = hash.ComputeHash(new UTF8Encoding().GetBytes(password));
	    }
    	
	    public static C1_01_DigestDefault GetInstance(String password, String algorithm) {
		    return new C1_01_DigestDefault(password, algorithm);
	    }
    	
	    public int DigestSize {
            get {
                return digest.Length;
            }
	    }
    	
	    public String GetDigestAsHexString() {
	        return new BigInteger(1, digest).ToString(16);
	    }

    	
	    public bool CheckPassword(String password) {
            byte[] result = hash.ComputeHash(new UTF8Encoding().GetBytes(password));
            return Arrays.AreEqual(result, digest);
	    }
    	
	    public static void ShowTest(String algorithm) {
		    try {
			    C1_01_DigestDefault app = GetInstance("password", algorithm);
			    Console.WriteLine("Digest using " + algorithm + ": " + app.DigestSize);
			    Console.WriteLine("Digest: " + app.GetDigestAsHexString());
			    Console.WriteLine("Is the password 'password'? " + app.CheckPassword("password"));
			    Console.WriteLine("Is the password 'secret'? " + app.CheckPassword("secret"));
		    } catch (GeneralSecurityException e) {
                Console.WriteLine(e.Message);
		    }
	    }
    	
	    public static void TestAll() {
		    ShowTest("MD5");
		    ShowTest("SHA-1");
		    ShowTest("SHA-256");
		    ShowTest("SHA-384");
		    ShowTest("SHA-512");
		    ShowTest("RIPEMD160");
	    }
    	
	    static void Main(String[] args) {
		    TestAll();
            Console.ReadKey();
	    }
    }
}
C1_02_DigestBC.cs
/*
 * This class is part of the white paper entitled
 * "Digital Signatures for PDF documents"
 * written by Bruno Lowagie
 * 
 * For more info, go to: http://itextpdf.com/learn
 */

using System;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;

namespace signatures.chapter1
{
    class C1_02_DigestBC
    {
        protected byte[] digest;
	    protected IDigest hash;
    	
	    protected C1_02_DigestBC(String password, String algorithm) {
	        hash = DigestUtilities.GetDigest(algorithm);
	        byte[] bytes = new UTF8Encoding().GetBytes(password);
            hash.BlockUpdate(bytes, 0, bytes.Length);
	        digest = new byte[hash.GetDigestSize()];
	        hash.DoFinal(digest, 0);
	    }
    	
	    public static C1_02_DigestBC GetInstance(String password, String algorithm) {
		    return new C1_02_DigestBC(password, algorithm);
	    }
    	
	    public int DigestSize {
            get {
                return digest.Length;
            }
	    }
    	
	    public String GetDigestAsHexString() {
	        return new BigInteger(1, digest).ToString(16);
	    }

    	
	    public bool CheckPassword(String password) {
            byte[] bytes = new UTF8Encoding().GetBytes(password);
            hash.BlockUpdate(bytes, 0, bytes.Length);
            byte[] result = new byte[hash.GetDigestSize()];
            hash.DoFinal(result, 0);
            return Arrays.AreEqual(result, digest);
	    }
    	
	    public static void ShowTest(String algorithm) {
		    try {
			    C1_02_DigestBC app = GetInstance("password", algorithm);
			    Console.WriteLine("Digest using " + algorithm + ": " + app.DigestSize);
			    Console.WriteLine("Digest: " + app.GetDigestAsHexString());
			    Console.WriteLine("Is the password 'password'? " + app.CheckPassword("password"));
			    Console.WriteLine("Is the password 'secret'? " + app.CheckPassword("secret"));
		    } catch (GeneralSecurityException e) {
                Console.WriteLine(e.Message);
		    }
	    }
    	
	    public static void TestAll() {
		    ShowTest("MD5");
		    ShowTest("SHA-1");
		    ShowTest("SHA-224");
		    ShowTest("SHA-256");
		    ShowTest("SHA-384");
		    ShowTest("SHA-512");
		    ShowTest("RIPEMD128");
		    ShowTest("RIPEMD160");
		    ShowTest("RIPEMD256");
	    }
    	
	    static void Main(String[] args) {
		    TestAll();
            Console.ReadKey();
	    }
    }
}
C1_03_EncryptDecrypt.cs
/*
 * This class is part of the white paper entitled
 * "Digital Signatures for PDF documents"
 * written by Bruno Lowagie
 * 
 * For more info, go to: http://itextpdf.com/learn
 */

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Crypto.Encodings;

namespace signatures.chapter1
{
    class C1_03_EncryptDecrypt
    {
        protected Pkcs12Store store;
        public const String KEYSTORE = "../../../../resources/pkcs12";

        public C1_03_EncryptDecrypt(String keystore, String ks_pass) {
            store = new Pkcs12Store(new FileStream(keystore, FileMode.Open), ks_pass.ToCharArray());
	    }

        public X509CertificateEntry GetCertificate(String alias){
            return store.GetCertificate(alias);
        }

        public AsymmetricKeyParameter GetPublicKey(String alias) {
		    return GetCertificate(alias).Certificate.GetPublicKey();
	    }

        public AsymmetricKeyEntry GetPrivateKey(String alias) {
		    return store.GetKey(alias);
	    }

        public byte[] Encrypt(ICipherParameters parameters, String message) {
            List encryptedBytes = new List();
            IAsymmetricBlockCipher cipher = new RsaEngine();
            cipher = new Pkcs1Encoding(cipher);
            cipher.Init(true, parameters);
            byte[] messageBytes = new UTF8Encoding().GetBytes(message);
            int i = 0;
            int len = cipher.GetInputBlockSize();
            while (i < messageBytes.Length)
            {
                if (i + len > messageBytes.Length)
                    len = messageBytes.Length - i;
                byte[] hexEncodedCipher = cipher.ProcessBlock(messageBytes, i, len);
                encryptedBytes.AddRange(hexEncodedCipher);
                i += cipher.GetInputBlockSize();
            }
            byte[] cipherData = new byte[encryptedBytes.Count];
            encryptedBytes.CopyTo(cipherData);
            return cipherData;
        }
    	
        public String Decrypt(ICipherParameters parameters, byte[] message) {
            List encryptedBytes = new List();
            IAsymmetricBlockCipher cipher = new RsaEngine();
            cipher = new Pkcs1Encoding(cipher);
            cipher.Init(false, parameters);
            int i = 0;
            int len = cipher.GetInputBlockSize();
            while (i < message.Length)
            {
                if (i + len > message.Length)
                    len = message.Length - i;
                byte[] hexEncodedCipher = cipher.ProcessBlock(message, i, len);
                encryptedBytes.AddRange(hexEncodedCipher);
                i += cipher.GetInputBlockSize();
            }
            byte[] cipherData = new byte[encryptedBytes.Count];
            encryptedBytes.CopyTo(cipherData);
            return new UTF8Encoding().GetString(cipherData);
        }
        
        static void Main(string[] args)
        {
            C1_03_EncryptDecrypt app = new C1_03_EncryptDecrypt(KEYSTORE, "password");
            AsymmetricKeyParameter publicKey = app.GetPublicKey("demo");
            AsymmetricKeyEntry privateKey = app.GetPrivateKey("demo");
            Console.Write("Let's encrypt 'secret message' with a public key\n");
            byte[] encrypted = app.Encrypt(publicKey, "secret message");
            Console.WriteLine("Encrypted message: " + new BigInteger(1, encrypted).ToString(16));
            Console.Write("Let's decrypt it with the corresponding private key\n");
            String decrypted = app.Decrypt(privateKey.Key, encrypted);
            Console.WriteLine(decrypted);

            Console.Write("\nYou can also encrypt the message with a private key\n");
            encrypted = app.Encrypt(privateKey.Key, "secret message");
            Console.WriteLine("Encrypted message: " + new BigInteger(1, encrypted).ToString(16));
            Console.Write("Now you need the public key to decrypt it\n");
            decrypted = app.Decrypt(publicKey, encrypted);
            Console.WriteLine(decrypted);
            Console.ReadKey();
        }
    }
}
Contact

Still have questions? 

We're happy to answer your questions. Reach out to us and we'll get back to you shortly.

Contact us
Stay updated

Join 11,000+ subscribers and become an iText PDF expert by staying up to date with our new products, updates, tips, technical solutions and happenings.

Subscribe Now