using System; using System.IO; using System.Security; using System.Security.Cryptography; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Serialization; namespace JavaScience { public class SignFilehash{ const int AT_KEYEXCHANGE = 1; //keyspec values const int AT_SIGNATURE = 2; public static void Main() { const String ContainerName = "{EDEE793E-4FDB-47BC-A23A-EFC2A840E461}"; int KeyType = AT_KEYEXCHANGE; String filename, sigfilename, rsapubparms, resp; FileStream fs = null; Console.Write("Enter name of file to sign: "); filename = Console.ReadLine(); if(!File.Exists(filename)){ Console.WriteLine("File {0} not found. ", filename); return; } byte[] data1ToHash = SignFilehash.GetFileBytes(filename); Console.WriteLine("File has {0} bytes", data1ToHash.Length); SHA1Managed SHhash = new SHA1Managed(); // --- compute SHA-1 hash of ASCII file bytes byte[] hashvalue = SHhash.ComputeHash(data1ToHash); Console.WriteLine("\nSHA1 hash of file {0} ({1} bytes):\n{2}", filename, hashvalue.Length, BitConverter.ToString(hashvalue)); // --- compute the encrypted hash (RSA PKCS #1 version 1.5 signature) ----- byte[] sigvalue = SignFilehash.GetSignature(hashvalue, ContainerName, KeyType); if(sigvalue ==null){ Console.WriteLine("Couldn't get signature"); return; } Console.WriteLine("\nSigned Hash of file {0} ({1} bytes):\n{2}", filename, sigvalue.Length, BitConverter.ToString(sigvalue)); //------ Write signature to output file --------------- Console.Write("\nWrite encrypted hash (signature) to file? "); resp = Console.ReadLine(); if(resp.Equals("y") || resp.Equals("y") ||resp.Equals("yes") ||resp.Equals("YES")){ Console.Write("Enter name of output signature file: "); sigfilename = Console.ReadLine(); if (File.Exists(sigfilename)) { Console.WriteLine("File '{0}' already exists!", sigfilename); return; } try{ fs = new FileStream(sigfilename, FileMode.CreateNew); fs.Write(sigvalue, 0, sigvalue.Length); Console.WriteLine("\nWrote signature file '{0}'", sigfilename) ; } catch(Exception e) { Console.WriteLine(e.Message) ; } finally { fs.Close(); } } //------ Serialize RSAParams to store public key info. --------------- Console.Write("\nWrite public key information to file? "); resp = Console.ReadLine(); if(resp.Equals("y") || resp.Equals("y") ||resp.Equals("yes") ||resp.Equals("YES")){ Console.Write("Enter name of output PUBLIC KEY (serialized RSAParams) file: "); rsapubparms = Console.ReadLine(); if (File.Exists(rsapubparms)) { Console.WriteLine("File '{0}' already exists!", rsapubparms); return; } CspParameters cp = new CspParameters(); cp.KeyContainerName = ContainerName; cp.KeyNumber = KeyType; RSACryptoServiceProvider rsaCSP = new RSACryptoServiceProvider(cp); RSAParameters rsaParams = rsaCSP.ExportParameters(false); //only export public part Console.WriteLine("\nModulus\n {0}", BitConverter.ToString(rsaParams.Modulus)); Console.WriteLine("\nExponent\n {0}", BitConverter.ToString(rsaParams.Exponent)); fs = new FileStream(rsapubparms, FileMode.CreateNew); BinaryFormatter formatter = new BinaryFormatter(); try { formatter.Serialize(fs, rsaParams); Console.WriteLine("\nWrote RSAParameters file '{0}'", rsapubparms) ; } catch (SerializationException e) { Console.WriteLine("Failed to serialize: " + e.Message); } catch (Exception e) { Console.WriteLine(e.Message) ; } finally { fs.Close(); } } } private static byte[] GetFileBytes(String filename){ if(!File.Exists(filename)) return null; Stream stream=new FileStream(filename,FileMode.Open); int datalen = (int)stream.Length; byte[] filebytes =new byte[datalen]; stream.Seek(0,SeekOrigin.Begin); stream.Read(filebytes,0,datalen); stream.Close(); return filebytes; } private static byte[] GetSignature(byte[] HashValue, String ContainerName, int keyspec) { //--- automatically creates CrypoAPI key container with ContainerName and keyspec if doesn't already exist CspParameters cp = new CspParameters(); cp.KeyContainerName = ContainerName; cp.KeyNumber = keyspec; if(HashValue == null || HashValue.Length==0) return null; byte[] SignedHash=null; try{ RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(cp); RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(RSA); RSAFormatter.SetHashAlgorithm("SHA1"); SignedHash = RSAFormatter.CreateSignature(HashValue); } catch(CryptographicException e){ Console.WriteLine(e.Message) ; } return SignedHash; } } }