Digital signatures - chapter 1

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

1st November 2015
admin-marketing

These examples were written in the context of the white paper Digital Signatures for PDF documents.

C1_01_DigestDefault.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*
 * 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
 * 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/*
 * 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
 * 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*
 * 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
 * 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<byte> encryptedBytes = new List<byte>();
            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<byte> encryptedBytes = new List<byte>();
            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