Young创建一个签名,它用Alice的私钥加密,可以使用Young的公钥访问。因此保证该签名来自于Young。 首先,看看Main方法中的主要步骤:创建一个Young的秘钥,给字符串‘Young’签名。最后使用公钥验证该签名是否来之于Alice。要签名的信息使用Encoding类转换成一个字节数组。要把加密的起那么写入控制台,包含该签名的字节数组使用Convert.ToBase64.String
internal static CngKey aliceKeySignature; internal static byte[] alicePubkeyBlob; /// <summary> /// 应用程序的主入口点。 /// </summary> static void Main() { CreateKeys(); byte[] aliceData = Encoding.UTF8.GetBytes("Young"); byte[] aliceSignature = CreateSignature(aliceData,aliceKeySignature); Console.WriteLine("Young create signature:{0}", Convert.ToBase64String(aliceSignature)); if (VerifySignature(aliceData,aliceSignature,alicePubkeyBlob)) { Console.WriteLine("Young signature verified successfully"); } }注:千万不要使用Encoding类把加密的数据转化为字符串。Encoding类验证和转化Unicode不允许使用无效值,因此把字符串转回字节数组会得到另一个结果。
CreateKeys方法为Young创建新的秘钥对。因为这个密钥对存储在一个静态字段中,所以可以从其他方法中访问它。CnkKey的Create方法把算法作为一个参数,为算法定义密钥对。通过Export方法,导出密钥对中的公钥。这个公钥可以提供给Bob,来验证签名。Young保留其私钥。除了使用CngKey类创建对之外,还可以打开存储在密钥存储器中的已有密钥。通过Young在其私有存储器中有一个证书,其中包含了一个密钥对,该存储器可以使用CngKey.Open方法访问
static void CreateKeys() { aliceKeySignature = CngKey.Create(CngAlgorithm.ECDsaP256); alicePubkeyBlob = aliceKeySignature.Export(CngKeyBlobFormat.GenericPublicBlob); }有了密钥对,Young就可以使用ECDsaCng类创建签名。这个类的构造函数从Young那里接受包含公钥和私钥CngKey类。在使用私钥,通过SingData给数据签名
public static byte[] CreateSignature(byte[] data,CngKey key) { byte[] signature; using (var signingAlg=new ECDsaCng(key)) { signature = signingAlg.SignData(data); signingAlg.Clear(); } return signature; }要验证签名是否真的来之Young,Bob使用Young的公钥检查签名。包含公钥Bob的字节数组可以使用静态方法Import导入CngKey对象。然后使用ECDsaCng类,调用VerifyData方法来检查签名。
static bool VerifySignature(byte[] data,byte[] signature,byte[] pubKey) { bool retValue = false; using (CngKey key = CngKey.Import(pubKey, CngKeyBlobFormat.GenericPublicBlob)) using(var signingAlg=new ECDsaCng(key)) { retValue = signingAlg.VerifyData(data,signature); signingAlg.Clear(); } return retValue; }下面是一个比较复杂的例子,它使用Diffie Hellman算法交换一个对称秘钥,以进行安全的传输。Main方法包含了其主要功能。Alice创建了一条加密的消息,并把它发送给Bob。在此之前,要先为Alice和Bob创建秘钥对。Bob只能访问Alice 的公钥,Alice只能访问Bob 的公钥。
static void Main() { Run(); Console.ReadKey(); } PRivate async static void Run() { try { CreateKeys(); byte[] encrytpedData = await AliceSendsData("SECRET MESSAGES"); byte[] encrytpedData11= await BobReceivesData(encrytpedData); } catch (Exception e) { Console.WriteLine(e.Message); } }在CreateKeys方法的实现代码汇总,使用ECDiffieHellman256算法创建密钥。
static void CreateKeys() { aliceKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256); alicePubkeyBlob = aliceKey.Export(CngKeyBlobFormat.EccPublicBlob); bobKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256); bobPubkeyBlob = bobKey.Export(CngKeyBlobFormat.EccPublicBlob); } private async static Task<byte[]> AliceSendsData(string message) { Console.WriteLine("Alice sends message:{0}",message); byte[] rawData = Encoding.UTF8.GetBytes(message); byte[] encryptedData = null; using (var aliceAlgorithm=new ECDiffieHellmanCng(aliceKey)) using (CngKey bobPubKey=CngKey.Import(bobPubkeyBlob,CngKeyBlobFormat.EccPublicBlob)) { byte[] symmkey = aliceAlgorithm.DeriveKeyMaterial(bobPubKey); Console.WriteLine("Alice creates this sysmmmtric key with" + "Bob public key information:{0}", Convert.ToBase64String(symmkey)); using (var aes=new AesCryptoServiceProvider()) { aes.Key = symmkey; aes.GenerateIV(); using (ICryptoTransform encryptor=aes.CreateEncryptor()) using (MemoryStream ms=new MemoryStream()) { var cs = new CryptoStream(ms,encryptor,CryptoStreamMode.Write); await ms.WriteAsync(aes.IV,0,aes.IV.Length); cs.Write(rawData, 0, rawData.Length); cs.Close(); encryptedData = ms.ToArray(); } aes.Clear(); } } Console.WriteLine("Alice:message is encryted:{0}",Convert.ToBase64String(encryptedData)); Console.WriteLine(); return encryptedData; } private async static Task<byte[]> BobReceivesData(byte[] encrytedData) { Console.WriteLine("Bob receives encrypted data"); byte[] rawData =null; var aes = new AesCryptoServiceProvider(); int nBytes=aes.BlockSize; byte[] iv=new byte[nBytes]; for (int i = 0; i < iv.Length; i++) { iv[i] = encrytedData[i]; } using (var bobAlgorithm = new ECDiffieHellmanCng(bobKey)) using (CngKey alicePubKey = CngKey.Import(alicePubkeyBlob, CngKeyBlobFormat.EccPublicBlob)) { byte[] symmkey = bobAlgorithm.DeriveKeyMaterial(alicePubKey); Console.WriteLine("Bob creates this sysmmmtric key with" + "Alice public key information:{0}", Convert.ToBase64String(symmkey)); aes.Key = symmkey; aes.IV = iv; using (ICryptoTransform encryptor = aes.CreateEncryptor()) using (MemoryStream ms = new MemoryStream()) { var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write); await ms.WriteAsync(aes.IV, 0, aes.IV.Length); cs.Write(encrytedData, 0, encrytedData.Length-nBytes); cs.Close(); rawData = ms.ToArray(); Console.WriteLine("Bob:message is encryted:{0}", Convert.ToBase64String(rawData)); } } aes.Clear();这里写代码片
return rawData; }在运行结果的时候: int nBytes=aes.BlockSize; 超出了数组?不知道怎么样去解决
新闻热点
疑难解答