/* ' $Id: TestChileSign.cs $ ' $Date: 2013-09-04 20:05 $ ' $Author: dai $ ' This module uses methods from the CryptoSys (tm) PKI Toolkit available from ' <www.cryptosys.net/pki/>. ' Add a reference to `diCrSysPKINet.dll` in your project. ' *************************** COPYRIGHT NOTICE ****************************** ' This code was originally written by David Ireland and is copyright ' (C) 2013 DI Management Services Pty Ltd <www.di-mgt.com.au>. ' Provided "as is". No warranties. Use at your own risk. You must make your ' own assessment of its accuracy and suitability for your own purposes. ' It is not to be altered or distributed, except as part of an application. ' You are free to use it in any application, provided this copyright notice ' is left unchanged. ' ************************ END OF COPYRIGHT NOTICE ************************** */ using System; using System.Text; using CryptoSysPKI; namespace TestChileSign { class TestChileSign { static void Main(string[] args) { string strDigestHex, strPriKeyFile, strSigValue64; StringBuilder sbPassword; // A quick check to show we have correct reference to the CryptoSys PKI library... Console.WriteLine("PKI Version={0}", General.Version()); // OUR TEST INPUT DATA: // The digest value we made earlier... strDigestHex = "353CABFE369AAD9BEA21F5FA06CB367960FFB7D4"; // We do not have the signing key used in the SII example. We use a test private key... strPriKeyFile = "AlicePrivRSASign.key"; // CAUTION: do not hardcode password in production code... // NB we use a StringBuilder for security reasons sbPassword = new StringBuilder("password"); Console.WriteLine("SHA-1 message digest of <SignedInfo> = {0}", strDigestHex); strSigValue64 = SignSignedInfo(strDigestHex, strPriKeyFile, sbPassword.ToString()); Console.WriteLine("SignatureValue={0}", strSigValue64); Wipe.String(sbPassword); } /// <summary> /// Creates SignatureValue suitable for XML file /// </summary> /// <param name="strDigestHex">SHA-1 digest of canonicalized <SignedInfo> element in HEX format</param> /// <param name="strPriKeyFile">Signer's encrypted private key file</param> /// <param name="strPassword">Password for private key file</param> /// <returns>Signature value in base64 form</returns> static string SignSignedInfo(string strDigestHex, string strPriKeyFile, string strPassword) { StringBuilder sbPrivateKey; byte[] digest; byte[] block; int nkLen; string sigVal64; // Read in private key from key file sbPrivateKey = Rsa.ReadEncPrivateKey(strPriKeyFile, strPassword); if (sbPrivateKey.Length == 0) { Console.WriteLine("ERROR: reading private key file"); return ""; } // Get length of key in bytes (expecting 128) nkLen = Rsa.KeyBytes(sbPrivateKey); Console.WriteLine(" Key is {0} bytes long", nkLen); // Convert digest value from Hex form to Byte array // -- expecting exactly 20 bytes = 40 hex chars, padded on the left with '0's if necessary if (strDigestHex.Length != 40) { Console.WriteLine("ERROR: expecting exactly 40 hex chars in strDigestHex"); return ""; } digest = Cnv.FromHex(strDigestHex); Console.WriteLine(" Digest={0}", Cnv.ToHex(digest)); // Encode digest value for signature block = Rsa.EncodeDigestForSignature(nkLen, digest, HashAlgorithm.Sha1); Console.WriteLine(" EM: {0}", Cnv.ToHex(block)); // Sign using RSA private key block = Rsa.RawPrivate(block, sbPrivateKey.ToString()); Console.WriteLine(" SG: {0}", Cnv.ToHex(block)); // Convert the byte array to base64 encoding sigVal64 = Cnv.ToBase64(block); // Clean up private key data Wipe.String(sbPrivateKey); // Return base64-encoded signature value return sigVal64; } } }