Diskuze: Šifrování hesla
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 16 zpráv z 16.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Pokud jse o heslo v pravém slova smyslu, tak se nešifruje, ale hashuje a
ukládá se pouze tzv. "otisk". Pak se nerozšifrovává, ale porovnávají se
otisky zadaného a uloženého hesla. Heslo si třeba "osolíš" nějakým
dalším, tebou daným stringem, aby to pro případného narušitele bylo
ještě složitější zjistit...
Někde jsem kdysi našel toto
public string HashHesla(string salt, string heslo)
{
string SourceText = salt + heslo;
Byte[] a = Encoding.UTF8.GetBytes(SourceText);
Byte[] b;
SHA512Managed c = new SHA512Managed();
b = c.ComputeHash(a);
string HashText = Convert.ToBase64String(b);
return HashText;
}
Možná sem to blbě vysvětlil, já si potřebuju (no, spíš chci) někam
uložit přístupový údaje do SQL serveru tak, aby byly editovatelný bez
nové kompilace programu. Proto ten konf. soubor. Ale nechci, aby si je mohl
kdokoli přečíst. Proto je tam chci zapsat v zašifrovaném tvaru.
Mezitím jsem si řešení našel:
http://www.codeproject.com/…ng-data-in-C
Pokud se to ale má řešit jinak, za každou radu budu moc rád.
Můžeš mi Zdeněk Pavlátka sdělit, za co jsi mi dal "-"?
Nějak jsem nepobral, k čemu potřebuješ měnit přístupové údaje do DB?
On výslovně napsal že potřebuje mít možnost zpětného rozšifrování... S hashem ti přeji hodně štěstí.
Možná by to chtělo si ten můj příspěvek nejdřív přečíst, než ho ohodnotíš. Heslo, které lze jednoduše rozšifrovat je k ničemu. Proto jsem psal, že se přístupová hesla nešifrují, ale hashují.
Ale on ho potřebuje přečíst, aby se s ním dostal do té DB... Hodně štěstí s hashem
A to je právě ten nesmysl, proč by mělo být heslo k DB v nějakém config souboru, když je v connectionstringu? Jak často je třeba měnit heslo pro přístup do DB?
Protože connectionString se běžně ukládá do config souborů. ConnectionString je závislý na prostředí, ve kterém je aplikace nasazená, takže je výhodné mít ho v konfiguraci, aby mohla stejná aplikace pracovat v rámci různých podmínek. Tradičně máš vývojové, testovací a produkční prostředí, každé z nich má zcela odlišnou konfiguraci. Na produkčním prostředí se chrání přístupové informace pomocí šifrování, ne hashování. Proč vlastně odpovídáš na otázky v oblasti, kterou jsi nikdy neviděl?
To máš těžké, šifrování slouží k nějakému účelu, který musí být jasně definován a úplně ty údaje odchránit nejde.
Konfigurační soubor se dá zašifrovat, zkus na google hledat ".net config encryption". Výsledkem je nečitelný config nebo jeho části, které .NET configuration automaticky načte a dešifruje. Tímhle přístupem se chráníš proti krádeži config souborů, protože na jiném stroji budou nečitelné. Údaje ale neochráníš před člověkem, který má k počítači fyzický přístup.
To, co sis našel, tedy manuální šifrování údajů, má dvě nevýhody. První a menší nevýhodou je, že to není až tak bezpečné, jak to vypadá, protože v šifrování nejspíš někde uděláš botu. Ale je poměrně těžké tohle překonat, takže to můžeš zkusit. Druhá a horší nevýhoda je, že zkušený programátor tvůj config dešifruje s menším úsilím, než tebe stálo ho zašifrovat. Můžeš zkusit obfuskaci, schovávání hesla, atd., ale to je jen o trochu více práce. Reversní analýza je v .NET velice jednoduchá věc.
Pokud chceš schovávat nějaké údaje, musíš si vydefinovat, před kým, za jakých podmínek a proč. Ale ve chvíli, kdy k aplikaci fyzicky pustíš útočníka, se už ochránit nedají.
Díky za odpovědi.
Mám představu uložit si ty údaje do XML v zašifrovaným tvaru, odtud si je načíst, rozšifrovat a v aplikaci složit ConnectionString. Ještě se podívám, jak se to dělá s konfiguračním souborem, ale myslím, že třeba takový config.xml by mi mohlo stačit.
To co potřebuješ jsou prostředky symetrické kryptografie. .NET toto podporuje. Na NETu najdeš spoustu příkladů. Takového něco malého jednoduchého na ukázku zde :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TvujNameSpace.Security
{
/// <summary>
/// Třída který používá jednoduché šifrování a dešifrovní textu.
/// </summary>
public static class TvujCryptor
{
private static byte[] keybBytes = new byte[32]
{
0xdd, 0xd9, 0xb4, 0x69, 0x25, 0x1f, 0xc0, 0xc7, 0xe2, 0x7a,
0x4a, 0x3f, 0xc3, 0xab, 0xf0, 0xb6, 0x2b, 0xdf, 0xa5, 0xfd, 0xb4, 0x14, 0x1f, 0x5a, 0x24, 0xb2, 0xfc, 0x41,
0x13, 0x46, 0x4e, 0xe6
};
private static byte[] ivBytes = new byte[16] { 0x76, 0xef, 0xbf, 0x43, 0x80, 0x3b, 0xaa, 0x9b, 0x90, 0x0b, 0xe8, 0xbd, 0xdc, 0xd5, 0xb8, 0x8f };
/// <summary>
/// Zašifruje text a vrátí jeho zašifrovanou podobu
/// </summary>
/// <param name="InputText">Vstupní text</param>
/// <returns>[cenzura]</returns>
public static string Crypt(string InputText)
{
string result = string.Empty;
byte[] inputBytes =
System.Text.Encoding.UTF8.GetBytes(InputText);
System.Security.Cryptography.RijndaelManaged aes = new System.Security.Cryptography.RijndaelManaged();
aes.Mode = System.Security.Cryptography.CipherMode.CBC;
aes.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
aes.Key = keybBytes;
aes.IV = ivBytes;
byte[] plainData = System.Text.Encoding.UTF8.GetBytes(InputText);
byte[] cipherData;
using (System.Security.Cryptography.ICryptoTransform enc = aes.CreateEncryptor())
{
cipherData = enc.TransformFinalBlock(plainData, 0, plainData.Length);
}
result = System.Convert.ToBase64String(cipherData, Base64FormattingOptions.None);
return result;
}
/// <summary>
/// Dešifruje text a vrátí "originál"
/// </summary>
/// <param name="InputCrypt">[cenzura]</param>
/// <returns>[cenzura]</returns>
public static string Decrypt(string InputCrypt)
{
string result = string.Empty;
byte[] inputBytes =
System.Text.Encoding.UTF8.GetBytes(InputCrypt);
System.Security.Cryptography.RijndaelManaged aes = new System.Security.Cryptography.RijndaelManaged();
aes.Mode = System.Security.Cryptography.CipherMode.CBC;
aes.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
aes.Key = keybBytes;
aes.IV = ivBytes;
byte[] cipherData = System.Convert.FromBase64String(InputCrypt);
byte[] plainData;
using (System.Security.Cryptography.ICryptoTransform dec = aes.CreateDecryptor())
{
plainData = dec.TransformFinalBlock(cipherData, 0, cipherData.Length);
}
result = System.Text.Encoding.UTF8.GetString(plainData);
return result;
}
}
}
Opatrně s IV v CBC módu, tímhle způsobem může šifra leakovat informace o heslu. IV by mělo být vždy náhodné a generované kryptograficky silným PRG.
J dík za info. Bez mučení se přiznám, že krypto podrobnostem nerozumím. Odkudpak si načerpal svoje vědomosti?
Zobrazeno 16 zpráv z 16.