MSDN上的一个不错的例子: 那从内存清除密码的句子有个问题。 需要再看看这个问题到底是怎么回事,怎么解决
cannot convert from Sytem.InPtr to ref string
把下面这句
public static extern bool ZeroMemory(ref string Destination, int Length);
用这句替换就OK了
internal static extern void ZeroMemory(IntPtr handle, int length);
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
namespace MSDNEncryExample
{
class Program
{
// Call this function to remove the key from memory after use for security.
[System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint = "RtlZeroMemory")]
internal static extern void ZeroMemory(IntPtr handle, int length);
// Function to Generate a 64 bits Key.
static string GenerateKey()
{
// Create an instance of Symetric Algorithm. Key and IV is generated automatically.
DESCryptoServiceProvider desCrypto = (DESCryptoServiceProvider)DESCryptoServiceProvider.Create();
// Use the Automatically generated key for Encryption.
return ASCIIEncoding.ASCII.GetString(desCrypto.Key);
}
static void EncryptFile(string sInputFilename, string sOutputFilename, string sKey)
{
// Create a file stream to read the data to be encrypted
FileStream fsInput = new FileStream(sInputFilename,FileMode.Open,FileAccess.Read);
//Crete a file stream for the encrypted data
FileStream fsEncrypted = new FileStream(sOutputFilename,FileMode.Create,FileAccess.Write);
// Create encryptor by usin the key
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
ICryptoTransform desencrypt = DES.CreateEncryptor();
// Create a CrytoStream to link the encrypted stream and the encryptor
CryptoStream cryptostream = new CryptoStream(fsEncrypted,desencrypt,CryptoStreamMode.Write);
// Read the file stream to bytes array
byte[] bytearrayinput = new byte[fsInput.Length];
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
// Encrypt the byte array by using the CryptoStream
cryptostream.Write(bytearrayinput,0,bytearrayinput.Length);
// Close the file streams
cryptostream.Close();
fsInput.Close();
fsEncrypted.Close();
}
static void DecryptFile(string sInputFilename,string sOutputFilename,string sKey)
{
// Set the DESCryptoServiceProvider class
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
//A 64 bit key and IV is required for this provider.
//Set secret key For DES algorithm.
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
//Set initialization vector.
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
//Create a file stream to read the encrypted file back.
FileStream fsread = new FileStream(sInputFilename,FileMode.Open,FileAccess.Read);
//Create a DES decryptor from the DES instance.
ICryptoTransform desdecrypt = DES.CreateDecryptor();
//Create crypto stream set to read and do a
//DES decryption transform on incoming bytes.
CryptoStream cryptostreamDecr = new CryptoStream(fsread,desdecrypt,CryptoStreamMode.Read);
//Print the contents of the decrypted file.
StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);
fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd());
fsDecrypted.Flush();
fsDecrypted.Close();
}
static void Main(string[] args)
{
// Must be 64 bits, 8 bytes.
// Distribute this key to the user who will decrypt this file.
string sSecretKey;
// Get the Key for the file to Encrypt.
sSecretKey = GenerateKey();
// For additional security Pin the key.
GCHandle gch = GCHandle.Alloc(sSecretKey, GCHandleType.Pinned);
// Encrypt the file.
EncryptFile(@"C:\MyData.txt",@"C:\Encrypted.txt",sSecretKey);
// Decrypt the file.
DecryptFile(@"C:\Encrypted.txt",@"C:\Decrypted.txt",sSecretKey);
// Remove the Key from memory.
ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2);
gch.Free();
}
}
}
另外一个例子
using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;
class RijndaelSample
{
static void Main()
{
try
{
// Create a new Rijndael object to generate a key
// and initialization vector (IV).
Rijndael RijndaelAlg = Rijndael.Create();
// Create a string to encrypt.
string sData = "Here is some data to encrypt.";
string FileName = "CText.txt";
// Encrypt text to a file using the file name, key, and IV.
EncryptTextToFile(sData, FileName, RijndaelAlg.Key, RijndaelAlg.IV);
// Decrypt the text from a file using the file name, key, and IV.
string Final = DecryptTextFromFile(FileName, RijndaelAlg.Key, RijndaelAlg.IV);
// Display the decrypted string to the console.
Console.WriteLine(Final);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadLine();
}
public static void EncryptTextToFile(String Data, String FileName, byte[] Key, byte[] IV)
{
try
{
// Create or open the specified file.
FileStream fStream = File.Open(FileName, FileMode.OpenOrCreate);
// Create a new Rijndael object.
Rijndael RijndaelAlg = Rijndael.Create();
// Create a CryptoStream using the FileStream
// and the passed key and initialization vector (IV).
CryptoStream cStream = new CryptoStream(fStream,
RijndaelAlg.CreateEncryptor(Key, IV),
CryptoStreamMode.Write);
// Create a StreamWriter using the CryptoStream.
StreamWriter sWriter = new StreamWriter(cStream);
try
{
// Write the data to the stream
// to encrypt it.
sWriter.WriteLine(Data);
}
catch (Exception e)
{
Console.WriteLine("An error occurred: {0}", e.Message);
}
finally
{
// Close the streams and
// close the file.
sWriter.Close();
cStream.Close();
fStream.Close();
}
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("A file error occurred: {0}", e.Message);
}
}
public static string DecryptTextFromFile(String FileName, byte[] Key, byte[] IV)
{
try
{
// Create or open the specified file.
FileStream fStream = File.Open(FileName, FileMode.OpenOrCreate);
// Create a new Rijndael object.
Rijndael RijndaelAlg = Rijndael.Create();
// Create a CryptoStream using the FileStream
// and the passed key and initialization vector (IV).
CryptoStream cStream = new CryptoStream(fStream,
RijndaelAlg.CreateDecryptor(Key, IV),
CryptoStreamMode.Read);
// Create a StreamReader using the CryptoStream.
StreamReader sReader = new StreamReader(cStream);
string val = null;
try
{
// Read the data from the stream
// to decrypt it.
val = sReader.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("An error occurred: {0}", e.Message);
}
finally
{
// Close the streams and
// close the file.
sReader.Close();
cStream.Close();
fStream.Close();
}
// Return the string.
return val;
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("A file error occurred: {0}", e.Message);
return null;
}
}
}
这个
CryptoStream Class
Defines a stream that links data streams to cryptographic transformations. CryptoSteam类提供数据流和加密传递之间的链接。
关于ZeroMemory
ZeroMemory Macro
Fills a block of memory with zeros.
To avoid any undesired effects of optimizing compilers, use the SecureZeroMemory function.
Parameters
-
Destination [in]
-
A pointer to the starting address of the block of memory to fill with zeros.
-
Length [in]
-
The size of the block of memory to fill with zeros, in bytes.
Return Value
This macro has no return value.
Remarks
Many programming languages include syntax for initializing complex variables to zero. There can be differences between the results of these operations and the ZeroMemory function. Use ZeroMemory to clear a block of memory in any programming language.
This macro is defined as the RtlZeroMemory macro. For more information, see Winbase.h and Winnt.h.