XML文件的加密和解密

时间:2013-11-11 16:16:10

标签: c#

我想加密XML文件并在c#中的另一台机器上对其进行解密。请帮忙......

我已经尝试过RSA算法和RijndaelManaged密钥,但无法在不同的机器上解密文件。

1 个答案:

答案 0 :(得分:1)

从问题描述中,您可能正在研究对称加密算法。这是应该让你开始的东西:

public class Key {
  public string Password { get; set; }
  public byte[] Salt { get; set; }
  public string Vector { get; set; }
  public PaddingMode? Padding { get; set; }
}

public class AesCryptor {
  private const int HASH_SIZE = 32;
  private ICryptoTransform m_Decryptor;
  private ICryptoTransform m_Encryptor;
  private TimeSpan m_Validity;

  // Methods
  public AesCryptor(Key key, TimeSpan validity) {
    if (key == null) {
      throw new ArgumentNullException("key");
    }
    m_Validity = validity;
    using (AesManaged aes = new AesManaged()) {
      aes.Mode = CipherMode.CBC;
      aes.Key = new Rfc2898DeriveBytes(key.Password, key.Salt).GetBytes(aes.KeySize / 8);
      aes.IV = Encoding.ASCII.GetBytes(key.Vector);
      if (key.Padding.HasValue) {
        aes.Padding = key.Padding.Value;
      }
      m_Encryptor = aes.CreateEncryptor();
      m_Decryptor = aes.CreateDecryptor();
    }
  }

  private static bool CompareArray(byte[] first, byte[] second) {
    if (first.Length != second.Length) {
      return false;
    }
    for (int i = 0; i < first.Length; i++) {
      if (first[i] != second[i]) {
        return false;
      }
    }
    return true;
  }

  public byte[] Decrypt(byte[] encryptedData) {
    byte[] hash;
    if (encryptedData == null) {
      throw new ArgumentNullException("encryptedData");
    }
    byte[] buffer = m_Decryptor.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
    using (SHA256 sha = SHA256.Create()) {
      hash = sha.ComputeHash(buffer, 0, buffer.Length - HASH_SIZE);
    }
    byte[] orginalHash = new byte[HASH_SIZE];
    Buffer.BlockCopy(buffer, buffer.Length - HASH_SIZE, orginalHash, 0, HASH_SIZE);
    if (!CompareArray(orginalHash, hash)) {
      throw new Exception("Hash match failure.");
    }
    if (m_Validity != TimeSpan.Zero) {
      DateTime timestamp = new DateTime(BitConverter.ToInt64(buffer, (buffer.Length - HASH_SIZE) - 8));
      TimeSpan delta = (TimeSpan)(DateTime.Now - timestamp);
      if (delta > m_Validity) {
        throw new Exception("Timestamp too old.");
      }
    }
    byte[] result = new byte[(buffer.Length - HASH_SIZE) - 8];
    Buffer.BlockCopy(buffer, 0, result, 0, (buffer.Length - HASH_SIZE) - 8);
    return result;
  }

  public byte[] Encrypt(byte[] data) {
    byte[] hash;
    if (data == null) {
      throw new ArgumentNullException("data");
    }
    byte[] buffer = new byte[(data.Length + 8) + HASH_SIZE];
    Buffer.BlockCopy(data, 0, buffer, 0, data.Length);
    Buffer.BlockCopy(BitConverter.GetBytes(DateTime.Now.Ticks), 0, buffer, data.Length, 8);
    using (SHA256 sha = SHA256.Create()) {
      hash = sha.ComputeHash(buffer, 0, buffer.Length - HASH_SIZE);
    }
    Buffer.BlockCopy(hash, 0, buffer, buffer.Length - HASH_SIZE, HASH_SIZE);
    return m_Encryptor.TransformFinalBlock(buffer, 0, buffer.Length);
  }
}

用法:

  var myKey = new Key {
    Password = "whatever,nevermind@$",
    Vector = "Q^!#g1353hdhjs*-",
    Salt = new byte[] { 0x33, 0x4d, 0x56, 0x4f, 1, 0x22, 15, 0x7f }
  };
  var cryptor = new AesCryptor(myKey, TimeSpan.Zero);
  // this will encrypt c:\test.xml into byte array
  byte[] encrypted = cryptor.Encrypt(File.ReadAllBytes(@"c:\test.xml"));
  // this will persist encrypted byte array into file c:\test-encrypted.bin
  File.WriteAllBytes(@"c:\test-encrypted.bin", encrypted);
  // this will load & decrypt bytes from file c:\test-encrypted.bin
  byte[] decrypted = cryptor.Decrypt(File.ReadAllBytes(@"c:\test-encrypted.bin"));
  // this will write decrypted bytes into c:\test-decrypted.xml
  File.WriteAllBytes(@"c:\test-decrypted.xml", decrypted);
相关问题