//---------------------------------------------------------------------------------- public static byte[] DecryptRsaPrivateKey ( string algoritm , string code , string password , byte[] data ) { string dn = "DES"; string an = string.Empty; int ks = 0; int bs = 0; int fs = 0; if ((algoritm = algoritm.ToUpper()).StartsWith("AES")) { an = "Rijndael"; bs = 128; fs = 128; } switch (algoritm) { case "DES-CBC": an = dn; ks = 64; bs = 64; break; case "DES-EDE3-CBC": an = "TripleDES"; ks = 192; bs = 64; break; case "AES-128-CBC": ks = 128; break; case "AES-192-CBC": ks = 192; break; case "AES-256-CBC": ks = 256; break; default: throw new CryptographicException("\"" + algoritm + "\" is not supported!"); } using (SymmetricAlgorithm sa = SymmetricAlgorithm.Create(an)) { sa.KeySize = ks; sa.BlockSize = bs; ks /= 8; if (fs > 0) { sa.FeedbackSize = fs; } byte[] iv = new byte[code.Length / 2]; for (int i = 0, l = iv.Length; i < l; ++i) { iv[i] = Convert.ToByte(code.Substring(i * 2, 2), 16); } byte[] b, d, h, k, p = Encoding.ASCII.GetBytes(password); using (MD5 m = MD5.Create()) { if (algoritm.StartsWith(dn)) // DES or 3DES { int n = 16; k = new byte[p.Length + iv.Length]; h = new byte[k.Length + n]; d = new byte[32]; Array.Copy(p, k, p.Length); Array.Copy(iv, 0, k, p.Length, iv.Length); Array.Clear(p, 0, p.Length); for (int i = 0; i < 2; ++i) { if (i == 0) { p = k; } else { Array.Copy(p, h, p.Length); Array.Copy(k, 0, h, p.Length, k.Length); Array.Clear(p, 0, p.Length); p = h; } Array.Copy(p = m.ComputeHash(p), 0, d, i * n, p.Length); } Array.Clear(h, 0, h.Length); } else // AES: { k = new byte[p.Length + 8]; h = new byte[ks + iv.Length]; Array.Copy(p, k, p.Length); Array.Copy(iv, 0, k, p.Length, 8); // Salt. for (int n, i = 0, l = h.Length; i < l;) { d = m.ComputeHash(k); if (d.Length > (n = l - i)) { b = new byte[n]; Array.Copy(d, b, b.Length); Array.Clear(d, 0, d.Length); d = b; } Array.Copy(d, 0, h, i, d.Length); if ((i += d.Length) < h.Length) { Array.Clear(k, 0, k.Length); k = new byte[d.Length + p.Length + 8]; Array.Copy(d, k, d.Length); Array.Copy(p, 0, k, d.Length, p.Length); Array.Copy(iv, 0, k, d.Length + p.Length, 8); } Array.Clear(d, 0, d.Length); } d = h; } } Array.Clear(k, 0, k.Length); k = new byte[ks]; Array.Copy(d, k, k.Length); Array.Clear(d, 0, d.Length); Array.Clear(p, 0, p.Length); data = OpenSSL.Decrypt(sa, k, iv, data); Array.Clear(k, 0, k.Length); Array.Clear(iv, 0, iv.Length); } return(data); }
//---------------------------------------------------------------------------------- public static void SetEncryptedPrivateKey ( RSACryptoServiceProvider rsa , byte[] data , string password ) { byte[] OIDpkcs5PBES2 = { 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0D }; byte[] OIDpkcs5PBKDF2 = { 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0C }; byte[] OIDdesEDE3CBC = { 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x07 }; using (MemoryStream ms = new MemoryStream(data)) { using (BinaryReader br = new BinaryReader(ms)) { int n = br.ReadUInt16(); if (n == 0x8130) { br.ReadByte(); } else if (n == 0x8230) { br.ReadInt16(); } else { throw new CryptographicException(OpenSSL.MSG_WRONG_OSSL_DATA); } if ((n = br.ReadUInt16()) == 0x8130) { br.ReadByte(); } else if (n == 0x8230) { br.ReadInt16(); } byte[] b = br.ReadBytes(11); if (!OpenSSL.CompareByteArray(b, OIDpkcs5PBES2)) { throw new CryptographicException(OpenSSL.MSG_WRONG_OSSL_DATA); } Array.Clear(b, 0, b.Length); if ((n = br.ReadUInt16()) == 0x8130) { br.ReadByte(); } else if (n == 0x8230) { br.ReadInt16(); } if ((n = br.ReadUInt16()) == 0x8130) { br.ReadByte(); } else if (n == 0x8230) { br.ReadInt16(); } b = br.ReadBytes(11); if (!OpenSSL.CompareByteArray(b, OIDpkcs5PBKDF2)) { throw new CryptographicException(OpenSSL.MSG_WRONG_OSSL_DATA); } Array.Clear(b, 0, b.Length); if ((n = br.ReadUInt16()) == 0x8130) { br.ReadByte(); } else if (n == 0x8230) { br.ReadInt16(); } if (br.ReadByte() != 0x04) { throw new CryptographicException(OpenSSL.MSG_WRONG_OSSL_DATA); } byte[] salt = br.ReadBytes(br.ReadByte()); if (br.ReadByte() != 0x02) { throw new CryptographicException(OpenSSL.MSG_WRONG_OSSL_DATA); } int iterations = 0; if ((n = br.ReadByte()) == 1) { iterations = br.ReadByte(); } else if (n == 2) { iterations = 256 * br.ReadByte() + br.ReadByte(); } else { throw new CryptographicException(OpenSSL.MSG_WRONG_OSSL_DATA); } if ((n = br.ReadUInt16()) == 0x8130) { br.ReadByte(); } else if (n == 0x8230) { br.ReadInt16(); } b = br.ReadBytes(10); if (!OpenSSL.CompareByteArray(b, OIDdesEDE3CBC)) { throw new CryptographicException(OpenSSL.MSG_WRONG_OSSL_DATA); } Array.Clear(b, 0, b.Length); if (br.ReadByte() != 0x04) { throw new CryptographicException(OpenSSL.MSG_WRONG_OSSL_DATA); } byte[] iv = br.ReadBytes(br.ReadByte()); if (br.ReadByte() != 0x04) { throw new CryptographicException(OpenSSL.MSG_WRONG_OSSL_DATA); } if ((n = br.ReadByte()) == 0x81) { n = br.ReadByte(); } else if (n == 0x82) { n = 256 * br.ReadByte() + br.ReadByte(); } data = br.ReadBytes(n); Rfc2898DeriveBytes db = new Rfc2898DeriveBytes(password, salt, iterations); byte[] bk = db.GetBytes(24); using (TripleDES td = TripleDES.Create()) b = OpenSSL.Decrypt(td, bk, iv, data); OpenSSL.SetPrivateKey(rsa, b); db.Reset(); Array.Clear(b, 0, b.Length); Array.Clear(data, 0, data.Length); Array.Clear(salt, 0, salt.Length); Array.Clear(iv, 0, iv.Length); Array.Clear(bk, 0, bk.Length); } } }