【问题标题】:AES encryption Java to c#AES加密Java到c#
【发布时间】:2013-10-31 20:30:41
【问题描述】:

我有以下代码在 java 中为我加密/解密数据

我需要在 Windows phone(8) 设备上用 C# 加密/解密数据,并且相同的数据应该能够使用此 java 代码解密/加密。

在 Windows Phone 中这个 java 代码在 C# 中的等效代码是什么??

public class AESencrp {
private static final String ALGO = "AES";
private static final byte[] keyValue = new byte[] { 'S', 'D', 'P', 'i', 'b', 'm', 'B','H', 'A', 'R', 'T','I', 'P', 'K', 'e', 'y' };

public static String encrypt(String Data) throws Exception {
    System.out.println(".............Encryption start............");
    Key key = generateKey();
    System.out.println("Key : " + key);
    Cipher c = Cipher.getInstance(ALGO);
    c.init(Cipher.ENCRYPT_MODE, key);
    byte[] encVal = c.doFinal(Data.getBytes());
    //System.out.println("encVal in byte[] : " + encVal);
    String encryptedValue = new BASE64Encoder().encode(encVal);
    System.out.println("encryptedValue byusing base64 : " + encryptedValue);
    System.out.println("..............Encryption End............");
    return encryptedValue;
}

public static String decrypt(String encryptedData) throws Exception {
    //final byte[] keyValue1 =  new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't','S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' };
    System.out.println("");
    System.out.println("");
    System.out.println(".............Decryption start............");
    Key key = generateKey();
    //Key key = new SecretKeySpec(keyValue1, ALGO);
    //System.out.println("Key : " + key);
    Cipher c = Cipher.getInstance(ALGO);
    c.init(Cipher.DECRYPT_MODE, key);
    byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
    //System.out.println("decryptedValue byusing base64 : " + decordedValue);
    byte[] decValue = c.doFinal(decordedValue);
   // System.out.println("decValue in byte[] : " + decValue);
    String decryptedValue = new String(decValue);
    System.out.println("String representation of decrypted value: " + decryptedValue);
    System.out.println(".............Decryption End............");
    return decryptedValue;
}
private static Key generateKey() throws Exception {
    Key key = new SecretKeySpec(keyValue, ALGO);
    System.out.println("key is " + keyValue  );
    return key;
}


public static void main(String[] args) throws Exception {
    String password = "encrypt_this";
    String passwordEnc = AESencrp.encrypt(password);
    String passwordDec = AESencrp.decrypt(passwordEnc);
    System.out.println("");System.out.println("");
    System.out.println("Plain Text : " + password);
    System.out.println("Encrypted Text : " + passwordEnc);
    System.out.println("Decrypted Text : " + passwordDec);
   }
}

似乎在这段代码中我只需要一个字符串 -

private static final byte[] keyValue = new byte[] { 'S', 'D', 'P', 'i', 'b', 'm', 'B','H', 'A', 'R', 'T','I', 'P', 'K', 'e', 'y' };

加密数据。

休息一切都是自动完成的。

我在这个链接上看到了一些解决方案

http://robtiffany.com/dont-forget-to-encrypt-your-windows-phone-7-data/

但它需要SALT值(我真的不知道它是什么???)

此外,该网站表示可以跳过一些步骤并使用预先创建的密钥和初始化向量。

在这件事上有什么帮助吗?

【问题讨论】:

  • @user2864740 有什么办法不使用“盐”???
  • @user2864740 我有java代码在服务器上运行,它不能被改变。我需要一段 C# (Windows Phone) 代码,它相当于这个 java 代码并产生完全相同的输出。有可能吗?
  • @user2864740 很抱歉,我对加密知之甚少。据我了解,java代码不需要盐值,而c#代码需要。我什至不知道我错在哪里。但感谢您的帮助。
  • 哦,我看错了(Java 代码需要镜像 C#)。
  • @user2864740 你觉得我想要的可行吗?

标签: java windows-phone-7 encryption windows-phone-8 aes


【解决方案1】:

您可以使用本机库来加密您的字符串,就像您的 Java 代码一样。 您只需要将 IV(Salt) 设置为所需大小为 16 的空数组。

我创建了一个类来进行加密/解密和转换(byte[]string 和反向)。

我希望你不要介意德国 cmets。只是还没时间翻译它们

static class AesClass
{
    public static byte[] EncryptStringToBytes(string plainText, byte[] Key)
    {
        // Überprüfe, ob alle Parameter gefüllt sind
        if ((String.IsNullOrEmpty(plainText) || (Key.Length <= 0 || Key == null)))
            throw new Exception("Both values mustn't be null or empty");

        byte[] encrypted;

        // Erstelle ein Objekt der Klasse Aes und
        // belege den Schlüssel, sowie den Salt (Initalisierungsvektor) mit den Parametern
        using (AesManaged aesAlgo = new AesManaged())
        {
            aesAlgo.Key = Key;
            aesAlgo.IV = new byte[16];
            //Verschlüsseler zur Umwandlung erstellen
            ICryptoTransform encryptor = aesAlgo.CreateEncryptor();

            // Erstelle Streams, welche für die Verschlüsselung genutzt werden
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        //Schreibe die Daten in den Stream
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }
        // Gebe die verschlüsselten Bytes aus dem Stream zurück
        return encrypted;
    }

    public static string DecryptStringFromBytes(byte[] cipherText, byte[] Key)
    {
        //Überprüfe, ob alle Parameter gefüllt sind
        if (((cipherText.Length <= 0 || cipherText == null) || (Key.Length <= 0 || Key == null)))
            throw new Exception("Both values mustn't be null or empty");

        //Erstelle eine Variable, in welcher später der entschlüsselte Text gespeichert wird
        string plaintext = null;

        try
        {
            // Erstelle ein Objekt von AES mit begrenzter Gültigkeit und
            // weiße dem Schlüssel (Key) und Salt (IV), die als Parameter übergebenen Werte zu
            using (AesManaged aesAlgo = new AesManaged())
            {
                aesAlgo.Key = Key;
                aesAlgo.IV = new byte[16];

                // Erstelle einen Entschlüsseler, welcher den Schlüssel und Salt nutzt,
                // um den ByteArray-Stream zu verändern (entschlüsseln)
                ICryptoTransform decryptor = aesAlgo.CreateDecryptor(aesAlgo.Key, aesAlgo.IV);

                // Erstelle Stream, welche zu Entschlüsselung genutzt werden
                // Ein Stream ist eine Darstellung einer geordneten Abfolge von Bytes
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            // Lese die entschlüsselten Bytes aus dem entschlüsselten Stream
                            // und füge sie komplett in die Variable, welche den entschlüsselte Text speichert.
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }
            }

        }
        catch (Exception ex)
        {
            //MessageBox.Show(ex.Message + "\r\nMöglichweise passt der aktuelle Schlüssel oder Salt nicht mit jenem überein, welcher die Daten verschlüsselt hat");
            return null;
        }
        return plaintext;
    }

    ///
    /// Wandle den String in ein ByteArray mit Base64
    /// Base64 ist ein Verfahren zur Kodierung von Binärdaten
    ///
    public static byte[] AESStringToByteArray(string cipher)
    {
        byte[] encByteArray = Convert.FromBase64String(cipher);
        return encByteArray;
    }

    ///
    /// Wandelt das übergebene Bytearray in einen menschenlesbaren String.
    /// Base64 ist ein Verfahren um Binärdaten zu kodieren
    ///
    ///Die Binärdaten
    /// Den gewandelten String
    public static string AESByteArrayToString(byte[] arr)
    {
        string base64 = Convert.ToBase64String(arr);
        return base64;
    }
}

您可以通过以下方式使用该类(我猜您在页面上调用):

private static byte[] keyValue = new byte[] { (int)'S', (int)'D', (int)'P', (int)'i', (int)'b', (int)'m', (int)'B', (int)'H', 
        (int)'A', (int)'R', (int)'T', (int)'I', (int)'P', (int)'K', (int)'e', (int)'y' };


private void Button_Encrypt_Click(object sender, RoutedEventArgs e)
{
    byte[] Data = AesClass.EncryptStringToBytes(TextBox_UnecryptedString.Text, keyValue);
    TextBox_EncryptedString.Text = AesClass.AESByteArrayToString(Data);
}

private void Button_Decrypt_Click(object sender, RoutedEventArgs e)
{
    byte[] cipherText = AesClass.AESStringToByteArray(TextBox_EncryptedString.Text); 
    TextBox_DecryptedString.Text = AesClass.DecryptStringFromBytes(cipherText, keyValue);
}

结果:

Java:

C#/WP7:

【讨论】:

  • 我试过这个方法,它适用于少于 16 个字符的字符串,两个输出都相同。但对于较大的字符串,它不起作用。有什么帮助???
  • 跟16字节/位IV有关系吗??
【解决方案2】:

AES 加密可以在 C# 和 Java 上完成,但有一些区别。

可悲的是,现在我记得它很差,但原生 wp7 密码术在密码方面存在一些问题。我已经写过herehere。 wp7最好下载BouncyCastle.Crypto库。


下载该库后,试试这个:

        private char[] keyValue = new char[] { 'S', 'D', 'P', 'i', 'b', 'm', 'B', 'H', 'A', 'R', 'T', 'I', 'P', 'K', 'e', 'y' };
        private char[] keyValue1 = new char[] { 'T', 'h', 'e', 'B', 'e', 's', 't', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' };
        private byte[] key;
        private byte[] key1;

        public AESPage()
        {
            InitializeComponent();
        }

        private void buttonEncrypt_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            key = keyValue.Select(x => Convert.ToByte(x)).ToArray();
            key1 = keyValue1.Select(s => Convert.ToByte(s)).ToArray();

            String password = "encrypt_this";
            String passwordEnc = encrypt(GetBytes(password));
            String passwordDec = decrypt(GetBytes(passwordEnc));
        }

        private String encrypt(byte[] Data)
        {
            IBufferedCipher cipher = CipherUtilities.GetCipher("AES");
            cipher.Init(true, new KeyParameter(key));
            byte[] encVal = cipher.DoFinal(Data);
            MemoryStream memoryStream = new MemoryStream();
            //Encrypt Data 
            memoryStream.Write(encVal, 0, encVal.Length);
            memoryStream.Flush();
            //Return encrypted String 
            byte[] decryptBytes = memoryStream.ToArray();
            return GetString(decryptBytes);
        }

        private String decrypt(byte[] encryptedData)
        {
            IBufferedCipher cipher = CipherUtilities.GetCipher("AES");
            cipher.Init(false, new KeyParameter(key1));
            byte[] decValue = cipher.DoFinal(encryptedData);
            MemoryStream memoryStream = new MemoryStream();
            //Decrypt Data 
            memoryStream.Write(decValue, 0, decValue.Length);
            memoryStream.Flush();
            //Return decrypted String 
            byte[] decryptBytes = memoryStream.ToArray();
            return GetString(decryptBytes);
        }

        private byte[] GetBytes(string str)
        {
            byte[] bytes = new byte[str.Length * sizeof(char)];
            System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
            return bytes;
        }

        private String GetString(byte[] result)
        {
            return System.Text.Encoding.UTF8.GetString(result, 0, result.Length);
        }

我已经为一个简单的带有单个按钮的 windows-phone 页面编写了这个,没有编写额外的类,比如你的 AESencrp,但我认为这个想法很清楚。

【讨论】:

    猜你喜欢
    • 2021-02-06
    • 1970-01-01
    • 1970-01-01
    • 2013-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-15
    相关资源
    最近更新 更多