Ошибка создания зашифрованного текста RSA в Java, не удается расшифровать в .net - PullRequest
1 голос
/ 08 мая 2019

Мне дали задание сгенерировать тикет на Java (OpenJDK 11) для входа на внешний сайт.В настоящее время этот тикет генерируется кодом .net (2.0), из которого у меня нет исходного кода, поэтому нам пришлось декомпилировать библиотеки DLL и работать оттуда.

Я получил модуль и открытый показатель (оба в кодировке base64) от провайдера.

MODULUS = "yBl8llKaMhEeMxI/fyUN07l5GwhQDlhAnNzoui....=";
EXPONENT = "AQAB";

Билет для генерации состоит из 3 частей: (1) данные: шифрование AES "username "(2) ключ: зашифрованный RSA ключ AES (3) IV: зашифрованный RSA IV

Целевой веб-сайт расшифровывает ключ и IV и использует их для расшифровки« данных ».Из декомпилированных DLL я вижу, что RSACryptoServiceProvider используется для RSA, а RijndaelManaged для AES.

Я генерирую открытый ключ:

BigInteger modulus = new BigInteger(1, Base64.decodeBase64(MODULUS.getBytes(UTF_8)));
BigInteger exponent = new BigInteger(1, Base64.decodeBase64(EXPONENT.getBytes(UTF_8)));

RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
publicKey = fact.generatePublic(rsaPubKey);

Используемый размер ключа AES составляет 128 бит:

 KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
 keyGenerator.init(128);
 MyKey = keyGenerator.generateKey();

Метод шифрования AES:

AESCipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(MyKey.getEncoded(), "AES"), new IvParameterSpec(AESCipher.getIV())

И метод шифрования RSA:

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
cipherData = cipher.doFinal(data);

Проблема в том, что я не могу понять, почему не удается войти в систему, мы просто получаем сообщение "сбой входа в систему", но не видим никаких деталей.

По декомпилированному коду я знаю, что OAEP не используется на стороне .net:

this.rsa = new RSACryptoServiceProvider();
Convert.ToBase64String(this.rsa.Encrypt(Encoding.UTF8.GetBytes(strData), false));

Я пробовал ключи разных размеров, режимы заполнения, ... но я 'у меня все из идей сейчас.Я что-то упускаю из виду?Я понимаю, что мы работаем с завязанными глазами, без дополнительной информации.

Код "Полный пример" ниже:

    String AES_TRANSFORMATION = "AES/CBC/PKCS5Padding";
    String RSA_TRANSFORMATION = "RSA/ECB/PKCS1Padding";
    String ALGORITHM = "AES";

    String MODULUS = "yBl8llKaMhEeMxI/fyUN07l5GwhQDlhAnNzoui...=";
    String EXPONENT = "AQAB";
    String USER_NAME = "myusernamehere";

    KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
    keyGenerator.init(keysize);
    String AES_KEY = keyGenerator.generateKey();

    Cipher AESCipher = Cipher.getInstance(AES_TRANSFORMATION);

    private void test() {
        BigInteger modulus = new BigInteger(1, Base64.decodeBase64(MODULUS.getBytes(UTF_8)));
        BigInteger exponent = new BigInteger(1, Base64.decodeBase64(EXPONENT.getBytes(UTF_8)));

        RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent);
        KeyFactory fact = KeyFactory.getInstance("RSA");
        publicKey = fact.generatePublic(rsaPubKey);

        String data = aes_encrypt((USER_NAME).getBytes());
        String key = rsa_encrypt(AES_KEY.getEncoded(), publicKey);
        String iv = rsa_encrypt(AESCipher.getIV(), publicKey);
    }

    private String aes_encrypt(byte[] data) {
        byte[] encryptedData = new byte[0];
        AESCipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(AES_KEY.getEncoded(), "AES"));
        encryptedData = AESCipher.doFinal(data);
        return Base64.encodeBase64String(encryptedData);
    }

    private String rsa_encrypt(byte[] data, PublicKey publicKey) {
        byte[] cipherData = new byte[0];
        Cipher cipher = Cipher.getInstance(RSA_TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        cipherData = cipher.doFinal(data);
        return Base64.encodeBase64String(cipherData);
    }
...