2013-08-06 33 views
10

Tôi đã được cung cấp mã C# này được viết bởi nhóm dịch vụ web cho thấy một số dịch vụ web mà tôi dự định tiêu thụ. Mật khẩu của tôi cần phải được mã hóa bằng mã này để dịch vụ web biết cách giải mã nó khi kết thúc.Dịch C# RSACryptoServiceProvider thành Mã JAVA

using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) 
{ 
    rsa.FromXmlString(publicKey); 
    byte[] plainBytes = Encoding.Unicode.GetBytes(clearText); 
    byte[] encryptedBytes = rsa.Encrypt(plainBytes, false); 
    return Convert.ToBase64String(encryptedBytes); 
} 

Tôi đang sử dụng Java để sử dụng dịch vụ web này và ngay bây giờ, tôi đang gặp sự cố khi dịch mã #C sang mã Java vì dịch vụ web đó không thể giải mã mật khẩu của tôi đúng cách.

Dưới đây là thất bại hiện tại của tôi: -

// my clear text password 
String clearTextPassword = "XXXXX"; 

// these values are provided by the web service team 
String modulusString = "..."; 
String publicExponentString = "..."; 

BigInteger modulus = new BigInteger(1, Base64.decodeBase64(modulusString.getBytes("UTF-8"))); 
BigInteger publicExponent = new BigInteger(1, Base64.decodeBase64(publicExponentString.getBytes("UTF-8"))); 

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

RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(modulus, publicExponent); 
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec); 

Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding"); 
cipher.init(Cipher.ENCRYPT_MODE, publicKey); 

String encodedEncryptedPassword = new String(Base64.encodeBase64(cipher.doFinal(clearTextPassword.getBytes("UTF-8")))); 

Tôi đã làm gì sai? Cảm ơn nhiều.

2013-08-07 - CẬP NHẬT

Tôi đã đọc this website và tôi nhận ra rằng giá trị mô đun của tôi và giá trị số mũ công khai đang không ở trong Hex. Vì vậy, tôi đã sửa đổi mã của mình một chút và thử với RSA/ECB/PKCS1PADDING như đã đề cập bởi @Dev.

// my clear text password 
String clearTextPassword = "XXXXX"; 

// these are the actual values I get from the web service team 
String modulusString = "hm2oRCtP6usJKYpq7o1K20uUuL11j5xRrbV4FCQhn/JeXLT21laKK9901P69YUS3bLo64x8G1PkCfRtjbbZCIaa1Ci/BCQX8nF2kZVfrPyzcmeAkq4wsDthuZ+jPInknzUI3TQPAzdj6gim97E731i6WP0MHFqW6ODeQ6Dsp8pc="; 
String publicExponentString = "AQAB"; 

Base64 base64Encoder = new Base64(); 

String modulusHex = new String(Hex.encodeHex(modulusString.getBytes("UTF-8"))); 
String publicExponentHex = new String(Hex.encodeHex(publicExponentString.getBytes("UTF-8"))); 

BigInteger modulus = new BigInteger(modulusHex, 16); 
BigInteger publicExponent = new BigInteger(publicExponentHex); 

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

RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(modulus, publicExponent); 
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec); 

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING"); 
cipher.init(Cipher.ENCRYPT_MODE, publicKey); 

String encodedEncryptedPassword = new String(base64Encoder.encode(cipher.doFinal(clearTextPassword.getBytes("UTF-8")))); 

Khi tôi nhấn webservice, tôi nhận được lỗi này: "Các dữ liệu được giải mã vượt quá mức tối đa cho mô đun này 128 byte." Có vẻ như mật khẩu văn bản rõ ràng vẫn chưa được mã hóa đúng cách.

Bất kỳ trợ giúp hoặc đề xuất nào được đánh giá cao. Cảm ơn.

2013-08-09 - GIẢI PHÁP

tôi gửi giải pháp làm việc cuối cùng của tôi bên dưới.

Trả lời

8

Tìm giải pháp.

String modulusString = "hm2oRCtP6usJKYpq7o1K20uUuL11j5xRrbV4FCQhn/JeXLT21laKK9901P69YUS3bLo64x8G1PkCfRtjbbZCIaa1Ci/BCQX8nF2kZVfrPyzcmeAkq4wsDthuZ+jPInknzUI3TQPAzdj6gim97E731i6WP0MHFqW6ODeQ6Dsp8pc="; 
String publicExponentString = "AQAB"; 

byte[] modulusBytes = Base64.decodeBase64(modulusString); 
byte[] exponentBytes = Base64.decodeBase64(publicExponentString); 
BigInteger modulus = new BigInteger(1, modulusBytes); 
BigInteger publicExponent = new BigInteger(1, exponentBytes); 

RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, publicExponent); 
KeyFactory fact = KeyFactory.getInstance("RSA"); 
PublicKey pubKey = fact.generatePublic(rsaPubKey); 
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING"); 
cipher.init(Cipher.ENCRYPT_MODE, pubKey); 

byte[] plainBytes = clearTextPassword.getBytes("UTF-16LE"); 
byte[] cipherData = cipher.doFinal(plainBytes); 
String encryptedStringBase64 = Base64.encodeBase64String(cipherData); 
+0

Tôi có cảm giác điều này sẽ là vấn đề giao thức đăng nhập thay vì mật mã. Chúng tôi đã đề cập đến mọi thứ khác. Vui vì bạn đã tìm ra. – Dev

+0

Khi tôi nhìn thấy 'Encoding.Unicode.GetBytes (String)' Tôi đang suy nghĩ 'UTF-8', không phải là' UTF-16LE', giả định rõ ràng và không chính xác, vì vậy hãy nắm bắt tốt về phía bạn. – Dev

+0

Cảm ơn vì điều đó - đã giải quyết được vấn đề của tôi. Hình như mọi người trong .NET thường sử dụng Encoding.Unicode.GetBytes/Encoding.Unicode.GetString không nhận ra nó không phải là UTF-8. – mvmn

1

Theo tài liệu MSDN trên RSACryptoServiceProvider.Encrypt, khi đối số thứ hai là false mật mã sử dụng đệm PKCS # 1 v1.5. Vì vậy, ngay lập tức dơi spec mã hóa của bạn là không chính xác.

Hãy thử RSA/ECB/PKCS1PADDING để thay thế.

Bạn đang chuyển đổi tài liệu chính của mình thành nhiều trong ví dụ mã thứ hai và bạn đã làm hỏng tài liệu chính của mình, khiến mã hóa của bạn nghĩ rằng bạn có nhiều tài liệu chính hơn bạn thực sự có và làm cho thư của bạn quá dài (kích hoạt lỗi của bạn) cũng như không thể hiểu được đối với mật mã giải mã ở đầu bên kia. Chuyển đổi trực tiếp thành các mảng byte và chuyển chúng sang BigInteger.

String modulusString = "..."; 
String publicExponentString = "..."; 

byte[] mod = Base64.decodeBase64(modulusString); 
byte[] e = Base64.decodeBase64(publicExponentString); 

BigInteger modulus = new BigInteger(1, mod); 
BigInteger publicExponent = new BigInteger(1, e); 
+0

Tôi đã thử "RSA/ECB/PKCS1PADDING" và cũng "RSA" cho mật mã. Cả hai đều thất bại. – limc

+0

@limc Bạn đang sử dụng lớp 'Base64' nào? – Dev

+0

Tôi hiện đang sử dụng Commons Codec. Ban đầu tôi sử dụng Codec của Spring, sau đó tôi nghĩ rằng đó sẽ là vấn đề vì vậy tôi chuyển sang Commons Codec ... nhưng chúng mang lại kết quả tương tự. – limc

Các vấn đề liên quan