Шифрование AES с использованием Java и WP7 - PullRequest
0 голосов
/ 17 августа 2011

У нас есть код для шифрования AES-128 в Java, и мы хотим получить некоторый эквивалентный код в WP7.

Однако мы сталкиваемся с проблемой: две реализации дают разные зашифрованные тексты

Здеськод, который мы используем:

Java-код

package com.emap.services;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AESEcrypt1 {

    static byte[] ibv = new byte[]{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
        0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};

    public String encryptData() {
        String message = "Testing AES encryption-decryption amlgorithm for WP7.";
        String encryptedStr = "";
        try {
            SecretKeySpec skeySpec = new SecretKeySpec("Passkey".getBytes(), "AES");
            IvParameterSpec iv = new IvParameterSpec(ibv);
            // Instantiate the cipher
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            byte[] encrypted = cipher.doFinal(message.getBytes());
            encryptedStr = Base64.encode(encrypted);
        } catch (BadPaddingException ex) {
            System.out.println("Error: " + ex.getMessage());
            encryptedStr = "error";
        } catch (IllegalBlockSizeException ex) {
            System.out.println("Error: " + ex.getMessage());
            encryptedStr = "error";
        } catch (InvalidAlgorithmParameterException ex) {
            System.out.println("Error: " + ex.getMessage());
            encryptedStr = "error";
        } catch (InvalidKeyException ex) {
            System.out.println("Error: " + ex.getMessage());
            encryptedStr = "error";
        } catch (NoSuchAlgorithmException ex) {
            System.out.println("Error: " + ex.getMessage());
            encryptedStr = "error";
        } catch (NoSuchPaddingException ex) {
            System.out.println("Error: " + ex.getMessage());
            encryptedStr = "error";
        } catch (Exception ex) {
            System.out.println("Error: " + ex.getMessage());
            encryptedStr = "error";
        }
        System.out.println("Encrypted: " + encryptedStr);
        return encryptedStr;
    }
}

WP7-код

static byte[] ibv = new byte[]{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
        0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};

public string Encrypt(string dataToEncrypt, string password)
//public string Encrypt(string dataToEncrypt)  
{
    AesManaged aes = null;
    MemoryStream memStream = null;
    CryptoStream crStream = null;
    try
    {
        //Generate a Key based on a Password and Salt      
        //Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt));
        Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(password, ibv);                
        aes = new AesManaged();
        aes.Key = rfc2898.GetBytes(aes.KeySize / 8);
        aes.IV = rfc2898.GetBytes(aes.BlockSize / 8);
        memStream = new MemoryStream();
        crStream = new CryptoStream(memStream, aes.CreateEncryptor(), CryptoStreamMode.Write);
        byte[] data = Encoding.UTF8.GetBytes(dataToEncrypt);
        crStream.Write(data, 0, data.Length);
        crStream.FlushFinalBlock();

        //Return Base 64 String                
        return Convert.ToBase64String(memStream.ToArray());
    }
    finally
    {
        //cleanup                
        if (crStream != null)
            crStream.Close();
        if (memStream != null)
            memStream.Close();
        if (aes != null)
            aes.Clear();
     }
}

Любая помощьбудет принята с благодарностью.

Ответы [ 2 ]

3 голосов
/ 17 августа 2011

Обратите внимание, что в Java у вас есть три части в обозначении шифра - алгоритм, режим (CBC против ECB и т. Д.) И заполнение. Вы должны соответствовать всем трем, а не только алгоритм. Если WP7 не позволит вам явно указать режим и отступы, выясните их и сопоставьте на стороне Java.

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

РЕДАКТИРОВАТЬ: для отладки проблем заполнения, тривиальный ключ является большой помощью. То есть ключ, который заставляет алгоритм выдавать копию своего открытого текста в виде зашифрованного текста. Например, для RSA это показатель с открытым показателем 1. Не уверен, что будет тривиальным ключом для AES - попробуйте все нули.

2 голосов
/ 17 августа 2011

Не похоже, что вы используете тот же ключ.В реализации Windows Phone 7 вы, кажется, правильно извлекаете ключ из пароля, в то время как код Java неправильно использует некоторую кодировку пароля напрямую.

См. Мой предыдущий ответ дляобщий обзор шифрования на основе пароля в Java.Он покажет вам, как получить ключ (в соответствии с PBKDF2 в RFC 2898), и описывает собственно генерацию и обмен вектором инициализации для каждого сообщения.


* 1010Комментарий Дж.Б. Низета к этому посту заставил меня более внимательно взглянуть на то, как вы используете данные ibv, и он прав: вы не используете один и тот же IV в обеих операциях.Он используется в качестве кода IV в коде Java, но в коде Windows он используется как «соль» для процесса получения ключа.Это две разные цели, и они должны использовать два разных значения.

Поскольку ibv является фиксированным значением, оно больше подходит для получения ключа (каждый пароль должен иметь одну уникальную соль).Каждое сообщение должно иметь случайно выбранный новый IV и отправляться с зашифрованным текстом.Вы можете использовать ibv в качестве salt в примере Java, на который я ссылался выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...