Плохие данные с помощью криптографии.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 может иметь несколько возможных кодировок, поэтому она вдвойне не подходит для передачи двоичных данных.

В общем, текст не должен напрямую использоваться для передачи двоичных данных. Данные должны быть закодированы в первую очередь.

Другие вопросы по тегам