Сап, криптач, я - нуб. Интересует тема шифрования файлов. В интернетах советуют GPG, но там по умолчанию используется шифрование с открытым ключом, а я где-то читал, что такие шифры менее стойкие нежели симметричные. Так же там есть возможность использовать симметричное шифрование, но тогда будут сложности с хранением ключа. Как делать правильно? Например, шифровать ключ от какого-нибудь AES асимметричным шифром и хранить его в отдельном файле, или ещё что. В инструкциях по GPG ничего на эту тему найти не смог.
>>20339 (OP) >>20339 (OP) троль что ле асимметричное и симметричное это разные методы для разных случаев. Сравнивать, что надёжней - это как сравнивать автомат и бронеавтомобиль. Ну для разных вещей это.
GPG использует и то, шифрование, и другое, как луковица.
Симметричое шифрование - самый баян. Оно использует пароль, который применяется для шифрования данных, и расшифровывания. Если ты хранишь файл с цопэ для себя и от майора, то этого тебе вполне достаточно. Если тебе надо передать цопэ другу Боре в Зажопинск, то помимо зашифрованного файла тебе придётся передать ему и этот пароль. Как это сделать так, чтобы тов. майор его не узнал и не прочёл этот файл тоже? Можешь передать его голубем, по телефону. Но если это невозможно, или не удобно, то тебе нужно асимметричное шифрование.
Его суть в том, что есть две половинки ключа. Одну половину, она называется секретный или приватный ключ, Боря должен держать в тайне и никогда никому не показывать. Другую половину (публичный или открытый ключ) Боря отдаёт тебе. Он может прислать её тебе по электронке. Ты при помощи этой половинки шифруешь пароль от своего архива с цопе и пересылаешь результат шифрования Боре.
Алгоритм асимметричного шифрования математически основан на том, что только Боря при помощи своей половинки (секретного ключа) может расшифровать твоё сообщение. Из него он получит пароль к симметричному шифру и вскорет архив с цопэ. А тов. майор никогда не сможет перехватить пароль симметричного шифра, т.к. тот никогда не передавался в открытом виде.
Собственно, PGP (или его GNU-сный аналог GPG) делает то же самое. Генерит случайный пароль, шифрует им файл, шифрует пароль открытым ключом АДРЕСАТА.
Ключевые слова: симметричные шифры AES, DES, DES3 . Асимметричные слова: RSA Процедура получения общего секретного ключа, неизвестного третьей стороне: DH (Diffie-Hellman).
using UnityEngine; using System; using System.Collections; using System.Security.Cryptography; using System.IO; using System.Text;
public class PlayerPrefsSet : MonoBehaviour {
//секретные коды, которые используются для шифровки static readonly string PasswordHash = "P@@Sw0rd"; static readonly string SaltKey = "S@LT&KEY"; static readonly string VIKey = "@1B2c3D4e5F6g7H8"; //Функция получения текстовой переменной из префов public string Text; void Update() { Debug.Log ("Encrypt ["+Encrypt (Text)+"]"); Debug.Log ("Decrypt ["+Decrypt(Encrypt (Text))+"]"); }
//функция, которая шифрает переменную, вникать не надо, тут просто процесс шифровки, его менять никак не надо public string Encrypt(string plainText) { byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8); var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros }; var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
byte[] cipherTextBytes;
using (var memoryStream = new MemoryStream()) { using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) { cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); cryptoStream.FlushFinalBlock(); cipherTextBytes = memoryStream.ToArray(); cryptoStream.Close(); } memoryStream.Close(); } return Convert.ToBase64String(cipherTextBytes); }
//функция дешифровки, такж, как и функция шифвровки
public string Decrypt(string encryptedText) { byte[] cipherTextBytes = Convert.FromBase64String(encryptedText); byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8); var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None };
var decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey)); var memoryStream = new MemoryStream(cipherTextBytes); var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read); byte[] plainTextBytes = new byte[cipherTextBytes.Length];
namespace RsaCryptoExample { static class Program { static void Main() { //lets take a new CSP with a new 2048 bit rsa key pair var csp = new RSACryptoServiceProvider(2048);
//how to get the private key var privKey = csp.ExportParameters(true);
//and the public key ... var pubKey = csp.ExportParameters(false);
//converting the public key into a string representation string pubKeyString; { //we need some buffer var sw = new System.IO.StringWriter(); //we need a serializer var xs = new System.Xml.Serialization.XmlSerializer(typeof(RSAParameters)); //serialize the key into the stream xs.Serialize(sw, pubKey); //get the string from the stream pubKeyString = sw.ToString(); }
//converting it back { //get a stream from the string var sr = new System.IO.StringReader(pubKeyString); //we need a deserializer var xs = new System.Xml.Serialization.XmlSerializer(typeof(RSAParameters)); //get the object back from the stream pubKey = (RSAParameters)xs.Deserialize(sr); }
//conversion for the private key is no black magic either ... omitted
//we have a public key ... let's get a new csp and load that key csp = new RSACryptoServiceProvider(); csp.ImportParameters(pubKey);
//we need some data to encrypt var plainTextData = "foobar";
//for encryption, always handle bytes... var bytesPlainTextData = System.Text.Encoding.Unicode.GetBytes(plainTextData);
//apply pkcs#1.5 padding and encrypt our data var bytesCypherText = csp.Encrypt(bytesPlainTextData, false);
//we might want a string representation of our cypher text... base64 will do var cypherText = Convert.ToBase64String(bytesCypherText);
/ some transmission / storage / retrieval and we want to decrypt our cypherText */
//first, get our bytes back from the base64 string ... bytesCypherText = Convert.FromBase64String(cypherText);
//we want to decrypt, therefore we need a csp and load our private key csp = new RSACryptoServiceProvider(); csp.ImportParameters(privKey);
//decrypt and strip pkcs#1.5 padding bytesPlainTextData = csp.Decrypt(bytesCypherText, false);
Как делать правильно? Например, шифровать ключ от какого-нибудь AES асимметричным шифром и хранить его в отдельном файле, или ещё что.
В инструкциях по GPG ничего на эту тему найти не смог.