2014-01-27 4 views
7

У меня есть следующий код подписи данных в C#Java эквивалент .NET RSACryptoServiceProvider с SHA-1

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); 

string PrivateKeyText = "<RSAKeyValue><Modulus>....</D></RSAKeyValue>"; 

rsa.FromXmlString(PrivateKeyText); 

string data = "my data";   

byte[] SignedByteData = rsa.SignData(Encoding.UTF8.GetBytes(data), new SHA1CryptoServiceProvider()); 

и я хочу воспроизвести тот же код в Java (Android):

String modulusElem = "..."; 
String expElem = "..."; 

byte[] expBytes = Base64.decode(expElem, Base64.DEFAULT); 
byte[] modulusBytes = Base64.decode(modulusElem, Base64.DEFAULT); 

BigInteger modulus = new BigInteger(1, modulusBytes); 
BigInteger exponent = new BigInteger(1, expBytes); 

try { 
    KeyFactory factory = KeyFactory.getInstance("RSA"); 

    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING"); 

    String data = "my data"; 

    MessageDigest md = MessageDigest.getInstance("SHA-1"); 
    byte[] hashedData = md.digest(data.getBytes("UTF-8")); 

    RSAPublicKeySpec pubSpec = new RSAPublicKeySpec(modulus, exponent); 

    PublicKey publicKey = factory.generatePublic(pubSpec); 

    cipher.init(Cipher.ENCRYPT_MODE, publicKey); 

    byte[] SignedByteData = cipher.doFinal(hashedData); 

} catch (Exception e){ 

} 

Но Я получаю несогласованные выходные байтовые массивы. Где я ошибаюсь и каково должно быть преобразование, используемое в Cipher.getInstance(...)?

+0

Проверьте это http://stackoverflow.com/questions/18089923/translating-c-sharp-rsacryptoserviceprovider-into-java-code –

+0

@ ZohraKhan, я написал код Java с этой должности в первую очередь. Метод, используемый в этом сообщении, - «Шифровать», в то время как я использую SignData, у которого встроена функция хэширования. –

ответ

6

Использование Signature.getInstance("SHA1withRSA"). Шифрование - это не то же самое, что генерация сигнатур. Различные механизмы заполнения для одного.


Обновление от Afshin

Комплексное решение. Обратите внимание на использование частного показателя, т.е. <D>, а общественное <Exponent>

String modulusElem = "..."; 
String dElem = "..."; 

byte[] modulusBytes = Base64.decode(modulusElem, Base64.DEFAULT); 
byte[] dBytes = Base64.decode(dElem, Base64.DEFAULT); 

BigInteger modulus = new BigInteger(1, modulusBytes); 
BigInteger d = new BigInteger(1, dBytes); 

String data = "my data";    

try { 
     Signature signature = Signature.getInstance("SHA1withRSA"); 

     KeyFactory factory = KeyFactory.getInstance("RSA"); 

     RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(modulus, d); 

     PrivateKey privateKey = factory.generatePrivate(privateKeySpec); 

     signature.initSign(privateKey); 

     signature.update(data.getBytes("UTF-8")); 

     byte[] SignedByteData = signature.sign(); 

} catch(Exception e) { 
    e.printStackTrace(); 
} 
+0

PS Я предполагаю, что здесь добавлено более старое дополнение PKCS # 1, документы RSACryptoServiceProvider забывают упомянуть используемый механизм заполнения. Один из моих более старых ответов также рассматривает это, и это кажется правильным. –

Смежные вопросы