Ошибка заполнения при использовании шифрования RSA в C # и дешифрования в Java - PullRequest
6 голосов
/ 20 августа 2009

В настоящее время я получаю следующую ошибку при использовании Java для расшифровки зашифрованной строки RSA в кодировке Base64, созданной на C #:

javax.crypto.BadPaddingException: Не PKCS # 1 тип блока 2 или заполнение нулями

Процесс установки между обменом из .NET и Java выполняется путем создания закрытого ключа в хранилище ключей .NET, затем из извлеченного файла PEM, созданного с помощью keytool, для создания версии JKS с закрытым ключом. Java загружает уже созданный JKS и декодирует строку Base64 в байтовый массив, а затем использует закрытый ключ для расшифровки.

Вот код, который у меня есть в C #, который создает зашифрованную строку:

public string Encrypt(string value) {
    byte[] baIn = null;
    byte[] baRet = null;
    string keyContainerName = "test";

    CspParameters cp = new CspParameters();
    cp.Flags = CspProviderFlags.UseMachineKeyStore;
    cp.KeyContainerName = keyContainerName;
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);

    // Convert the input string to a byte array 
    baIn = UnicodeEncoding.Unicode.GetBytes(value);

    // Encrypt
    baRet = rsa.Encrypt(baIn, false);

    // Convert the encrypted byte array to a base64 string
    return Convert.ToBase64String(baRet);
}

Вот код, который у меня есть на Java, который расшифровывает введенную строку:

public void decrypt(String base64String) {
    String keyStorePath = "C:\Key.keystore";
    String storepass = "1234";
    String keypass = "abcd";
    byte[] data = Base64.decode(base64String);
    byte[] cipherData = null;

    keystore = KeyStore.getInstance("JKS");
    keystore.load(new FileInputStream(keyStorePath), storepass.toCharArray());

    RSAPrivateKey privateRSAKey = (RSAPrivateKey) keystore.getKey(alias, keypass.toCharArray());

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

    System.out.println(new String(cipherData));
}

Кто-нибудь видит пропущенный шаг или где необходимо изменить отступ или элемент? Я часами читал на этом и других сайтах, но не нашел конкретного решения.

Ваша помощь очень ценится.

Спасибо. Матф

Ответы [ 5 ]

4 голосов
/ 31 мая 2010

У меня была точно такая же проблема, и я наконец-то нашел решение!

Я был упрям, используя PKCS1Padding, но мне не удалось заставить его работать.

Лучший результат, который я получил, используя "rsa.Encrypt (baIn, false)" * на стороне C # и "RSA / NONE / NoPadding" на стороне Java, был такой строки: "☻? o + _> ?? 5? l0Q * ??? *? R ▲ ??? ♀7 ...", за которой следует моя расшифрованная строка. Таким образом, он каким-то образом расшифровывался, но поскольку не было задано никакого заполнения, данные смещались. Поэтому я перепробовал все отступы, доступные в bouncycastle, но всегда получал ошибки, такие как «неправильный размер блока» или «неправильный хэш данных».

Поэтому я решил начать пробовать OAEP-заполнение, и мне, наконец, удалось заставить его работать, используя "rsa.Encrypt (baIn, true)" * на стороне C # и "RSA / NONE / OAEPWithSHA1AndMGF1Padding " на стороне Java!

Это сработало для меня, надеюсь, это сработает и для вас! Если это не работает, убедитесь, что вы используете правильный ключ, очень часто проблема возникает из-за ключа.

2 голосов
/ 13 апреля 2010

Я работаю над аналогичной проблемой, действующей между объектами .Net и iPhone в Objective-C, и я думаю, что ответ лежит в этом небольшом сокровище из документации RSACryptoServiceProvider:

В отличие от реализации RSA в неуправляемом CAPI, класс RSACryptoServiceProvider меняет порядок зашифрованного массива байтов после шифрования и перед расшифровкой. По умолчанию данные, зашифрованные классом RSACryptoServiceProvider, не могут быть расшифрованы функцией CAPI CryptDecrypt, а данные, зашифрованные методом CAPI CryptEncrypt, не могут быть расшифрованы классом RSACryptoServiceProvider.

Подробнее смотрите здесь: http://msdn.microsoft.com/en-us/library/s575f7e2(v=VS.90).aspx

2 голосов
/ 20 августа 2009

Проверьте, правильно ли вы обменяли ключ.

Попытка расшифровки с использованием неверного ключа неотличима от расшифровки плохо дополненных данных.

0 голосов
/ 31 июля 2013

У меня была такая же проблема при использовании Bouncy Castle 1.48, но это не было связано с ключами. Вместо этого я обнаружил, что должен был установить следующее системное свойство:

-Dorg.bouncycastle.pkcs1.strict=false
0 голосов
/ 24 сентября 2009

Я предполагаю, что версия C # испускает байты в формате с прямым порядком байтов, а версия Java импортирует байты, ожидая, что они будут в формате с прямым порядком байтов. Попробуйте поменять байты в baRet от начала до конца, прежде чем конвертировать их в base 64, и посмотрите, сможет ли ваша Java-программа их расшифровать.

Просто предположение.

...