Плохие данные с помощью криптографии.RC2
Существует особый рабочий процесс, в котором мы зашифровываем и дешифруем ввод. Внезапно вчера была зашифрованная строка, которую мы не смогли расшифровать.
Кажется, мои криптографические знания не достаточно хороши, чтобы решить эту проблему.
Код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Crypto
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
public static class Crypto
{
public static void Main()
{
//String NotWorking_dec = "鈦ꧪ㧘聯ꢮ玗硴廜᭮⸂濅�";
String enc ="mIAU::__*?";
//String dec = "砿첩뜞ꦽ嶾蝡泛ɝࠪ塤偏ꍨ";
Console.WriteLine(decrypt(dec));
//writeFile(encrypt(enc));
Console.ReadLine();
}
private static string key = "ZlKMpRwoPLmNXEpCLxEa6g==";
private static string iv = "U5ZB4W4bQqg=";
private static ICryptoTransform enc;
private static ICryptoTransform dec;
static Crypto()
{
RC2 rc = System.Security.Cryptography.RC2.Create();
enc = rc.CreateEncryptor(Convert.FromBase64String(key), Convert.FromBase64String(iv));
dec = rc.CreateDecryptor(Convert.FromBase64String(key), Convert.FromBase64String(iv));
}
public static String encrypt(String value)
{
byte[] input = toBytes(value);
return toString(enc.TransformFinalBlock(input, 0, input.Length));
}
public static String decrypt(String value)
{
byte[] input = toBytes(value);
Console.WriteLine(input.Length);
return toString(dec.TransformFinalBlock(input, 0, input.Length));
}
private static void writeFile(String value)
{
try
{
StreamWriter sw = new StreamWriter("output.tmp", true);
sw.WriteLine(value);
sw.Close();
}
catch (Exception ex) { }
}
private static byte[] toBytes(String value)
{
return Encoding.Unicode.GetBytes(value);
}
private static String toString(byte[] value)
{
return Encoding.Unicode.GetString(value);
}
}
}
Этот рабочий прогресс работает месяцами. Вы можете проверить это с помощью ввода
Miau::__*?
ты получаешь
砿첩뜞ꦽ嶾蝡泛ɝࠪ塤偏ꍨ
расшифруй и получишь снова
Miau::__*?
Но зашифрованная строка "鈦ꧪ㧘聯ꢮ玗硴廜᭮⸂濅 " выдает ошибки: (Конечно, мы использовали тот же ключ и iv)
BAD DATA
bei System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
bei System.Security.Cryptography.Utils._DecryptData(SafeKeyHandle hKey, Byte[] data, Int32 ib, Int32 cb, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode PaddingMode, Boolean fDone)
bei System.Security.Cryptography.CryptoAPITransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
bei Crypto.Crypto.decrypt(String value) in c:\Users\Td\Documents\Visual Studio 2013\Projects\Crypto\Crypto\Program.cs:Zeile 56.
bei Crypto.Crypto.Main() in c:\Users\Td\Documents\Visual Studio 2013\Projects\Crypto\Crypto\Program.cs:Zeile 23.
bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
bei System.AppDomain.nExecuteAssembly(RuntimeAssembly assembly, String[] args)
bei System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel)
bei System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()
bei System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
bei System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext)
bei System.Activator.CreateInstance(ActivationContext activationContext)
bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Threading.ThreadHelper.ThreadStart()
1 ответ
Вы не можете просто конвертировать случайные байты в строки и обратно. Не все байты являются допустимыми кодировками символов. Например, вам нужно применить кодировку base 64 к вашему двоичному зашифрованному тексту, если вам требуется текст. В противном случае вы потеряете данные, в зависимости от значения зашифрованного текста. И зашифрованный текст будет содержать случайные байтовые значения. Так что это может провалиться время от времени, как вы сейчас испытываете.
Java по умолчанию преобразует неизвестные байты в символы, например, создаст �
символ, если он не может преобразовать байт (ы) в символ. Вот почему эта конкретная строка терпит неудачу.
Кроме того, Unicode содержит много символов, которые нелегко распечатать, и даже символы, которые могут быть созданы с использованием двух кодовых точек Unicode или одного. Таким образом, строка Unicode может иметь несколько возможных кодировок, поэтому она вдвойне не подходит для передачи двоичных данных.
В общем, текст не должен напрямую использоваться для передачи двоичных данных. Данные должны быть закодированы в первую очередь.