Как зашифровать в C # .NET так же, как код Java - PullRequest
2 голосов
/ 05 марта 2010

Мне нужно отправить зашифрованную строку из личного ключа на веб-сервер для аутентификации. У меня есть клиентский код Java, который правильно генерирует зашифрованную строку (чтобы веб-сервер мог расшифровать ее с помощью открытого ключа). Я пытаюсь написать код C # для выполнения точно такого же шифрования, но не удалось.

Сначала в java было создано хранилище ключей с использованием keytool, похожего на это:

keytool -genkey -dname "cn=Application Test, ou=XXX, o=YYY, c=US" -alias AppTest -keypass AppTest -keystore AppTest.jks -storepass AppTest -validity 1800 -keyalg RSA

Тогда этот код Java правильно считывает хранилище ключей и шифрует данные (privateKey.getAlgorithm () возвращает «RSA»):

KeyStore ks = KeyStore.getInstance("JKS");
InputStream is = new FileInputStream("AppTest.jks");
ks.load(is, "AppTest".toCharArray());
is.close();
PrivateKey privateKey = (PrivateKey) ks.getKey(user, password.toCharArray());

// Encrypt with the private key
String stamp = "123456";
byte[] bytesStampUtf8Unencrypted = stamp.getBytes(Charset.forName("UTF-8"));
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] bytesTimestampUtf8Encrypted = cipher.doFinal(bytesStampUtf8Unencrypted);
String encrypted = new String((new Base64()).encode(bytesStampUtf8Unencrypted));

Все это прекрасно работает при передаче в веб-сервис. Затем я использовал keytool для преобразования из хранилища ключей java в сертификат PKCS12 для использования в моем приложении .NET:

keytool -importkeystore -srckeystore AppTest.keystore -destkeystore KEYSTORE.p12  -srcstoretype JKS -deststoretype PKCS12 -srcstorepass AppTest -deststorepass AppTest-srcalias AppTest -destalias AppTest -srckeypass AppTest -destkeypass AppTest -noprompt

Используя keytool, я сравнил отпечатки пальцев из хранилища ключей и файлов P12 - идентичные. Я думал, что следующий код C # должен работать:

X509Certificate2 myCertificate =
   new X509Certificate2(@"C:\Temp\KEYSTORE.p12", "AppTest");
RSACryptoServiceProvider privateKey =
   myCertificate.PrivateKey as RSACryptoServiceProvider;
String stamp = "123456";
byte[] buffer = Encoding.UTF8.GetBytes(stamp);
byte[] encryptedBytes = privateKey.Encrypt(buffer, false);
String encrypted = Convert.ToBase64String(encryptedBytes);

Он правильно читает преобразованный файл хранилища ключей, выполняет без проблем и генерирует то, что выглядит как зашифрованные данные, но веб-службе НЕ нравится зашифрованная строка (не может расшифровываться с помощью открытого ключа). Когда я заменил зашифрованную строку C # на зашифрованную строку Java (в отладчике) и отправил эту строку через программу C # в веб-службу - все это тоже работало - поэтому я уверен, что проблема заключается в процессе шифрования, а не в веб-сервисе связи.

У меня нет контроля над тем, как был сгенерирован исходный ключ (как хранилище ключей Java), и каким способом шифрования ожидается веб-служба. Я могу управлять только клиентом .NET, который взаимодействует с веб-службой на основе Java.

Мне не хватает какого-либо флага, параметра, переменной, что?

Ответы [ 2 ]

2 голосов
/ 05 марта 2010

Вы уверены, что алгоритм шифрования , режим блочного шифра и режим заполнения эквивалентны в вашей реализации C # по сравнению с вашей реализацией Java?

Редактировать: На самом деле для RSACryptoProvider вам, вероятно, не нужен режим шифрования / заполнения - посмотрите на пример на MSDN , в частности, на раздел об импорте информации открытого ключа через ImportParameters

0 голосов
/ 03 июня 2011

Это решение, которое трудно найти в рабочем состоянии для Encrypt в Java и Decrypt в .Net, и, наконец, я смог реализовать в одном из моих проектов, используя это, мы можем зашифровать любую строку в Java и расшифровать это в .Net заканчивается использованием API BouncyCastle.

Я использовал Blowfish для шифрования / дешифрования:

Вы можете ссылаться на файлы и т.д. для bouncycastle от: http://bouncycastle.org/latest_releases.html

Java-код

  import org.bouncycastle.util.encoders.UrlBase64;
  import org.bouncycastle.crypto.engines.BlowfishEngine;
  import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
  import org.bouncycastle.crypto.params.KeyParameter;
  import org.bouncycastle.util.Strings;

  public class EncryptString
  {
public static void main(String[] args) throws Exception
{
String plain = "UserName=\'pgupta\'&Channel=\'1\'&LevelID=\'1\'&LevelName=\'Super Star colony\'";
     String key = "x-392kla%3$*1f";
//To getBytes in UTF8 Encoding
byte[] inBytes = plain.getBytes("UTF8");
byte[] keyByte = key.getBytes("UTF8"); 

PaddedBufferedBlockCipher _cipher = new PaddedBufferedBlockCipher(new BlowfishEngine());

try
{
_cipher.init(true, new KeyParameter(keyByte));

           // Determine the minimum output buffer size
byte[] outBytes = new byte[_cipher.getOutputSize(inBytes.length)];

        // 'len' is the actual size returned
     int len = _cipher.processBytes(inBytes, 0, inBytes.length, outBytes, 0);

_cipher.doFinal(outBytes,len);

         System.out.println("encrypted: " + new String(UrlBase64.encode(outBytes)));
}
catch(Exception e)
     {
         System.out.println("Exception: " + e.toString());
     }

}
  }

C # код

using System;
using System.Collections.Generic;
using Org.BouncyCastle.Crypto.Paddings;
using System.Text;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Utilities.Encoders;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto;

public class Decrypt
{  

public string Decryption(string Request)
{
            String EncryptedS = Request;

            string convertHTML = string.Empty;
String key = ConfigurationSettings.AppSettings["EncDecKey"];//"123456789";

byte[] keyByte = Encoding.UTF8.GetBytes(key);   
try
{
byte[] result = BouncyCastleCrypto(false, UrlBase64.Decode(EncryptedS), key);
convertHTML = Encoding.UTF8.GetString(result);
}
catch (Org.BouncyCastle.Crypto.CryptoException ex)
{
convertHTML = "false";

}

return convertHTML;
}

private byte[] BouncyCastleCrypto(bool forEncrypt, byte[] input, string key)
{
try
{
byte[] keyByte = Encoding.UTF8.GetBytes(key);
_PaddedBufferedBlockCipherWithlowfish.Init(forEncrypt, new KeyParameter(keyByte));
byte[] outBytes = new byte[_PaddedBufferedBlockCipherWithlowfish.GetOutputSize(input.Length)];
int len = _PaddedBufferedBlockCipherWithlowfish.ProcessBytes(input, 0, input.Length, outBytes, 0);
_PaddedBufferedBlockCipherWithlowfish.DoFinal(outBytes, len);
return outBytes;

}
catch (Org.BouncyCastle.Crypto.CryptoException ex)
{
throw new CryptoException(ex.ToString());
}
}     
}

Примечание: пожалуйста, используйте один и тот же ключ на обоих концах.

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