Digital signatures - chapter 1
These examples were written in the context of the white paper Digital Signatures for PDF documents.
c1_01_digestdefault
JAVA
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();
}
}
C#
C#
/*
* 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
JAVA
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();
}
}
C#
C#
/*
* 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
JAVA
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);
}
}
C#
C#
/*
* 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();
}
}
}