país - Traducir C#RSACryptoServiceProvider en código JAVA
traductor hablando (2)
De acuerdo con los documentos de MSDN en RSACryptoServiceProvider.Encrypt
, cuando el segundo argumento es false
el cifrado utiliza el relleno PKCS # 1 v1.5. Así que desde el principio su especificación de cifrado es incorrecta.
Pruebe RSA/ECB/PKCS1PADDING
en RSA/ECB/PKCS1PADDING
lugar.
Está convirtiendo mucho el material clave en su segundo ejemplo de código y lo corrompió, lo que hace que su sistema de cifrado piense que tiene más material clave de lo que realmente tiene y hace que su mensaje sea demasiado largo (lo que desencadena el error) y también ininteligible. al cifrado de descifrado en el otro extremo. Convierte directamente a matrices de bytes y BigInteger
a 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);
Me dieron este código C # escrito por el equipo de servicio web que expone algunos servicios web que planeo consumir. Mi contraseña debe estar encriptada con este código para que el servicio web sepa cómo descifrarla en su extremo.
using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(publicKey);
byte[] plainBytes = Encoding.Unicode.GetBytes(clearText);
byte[] encryptedBytes = rsa.Encrypt(plainBytes, false);
return Convert.ToBase64String(encryptedBytes);
}
Estoy usando Java para consumir este servicio web y, en este momento, tengo problemas para traducir ese código #C en código Java porque ese servicio web no puede descifrar mi contraseña correctamente.
Aquí está mi intento fallido actual:
// 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"))));
¿Qué hice mal? Muchas gracias.
2013-08-07 - ACTUALIZACIÓN
Estaba leyendo este sitio web y me di cuenta de que mi valor de módulo y el valor de exponente público no están en Hex. Por lo tanto, modifiqué un poco mi código y lo intenté con RSA/ECB/PKCS1PADDING
como lo menciona @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"))));
Cuando presiono el servicio web, obtengo este error: "Los datos que se descifrarán excederán el máximo para este módulo de 128 bytes". Parece que la contraseña de texto claro aún no está encriptada correctamente.
Cualquier ayuda o sugerencia es muy apreciada. Gracias.
2013-08-09 - SOLUCIÓN
Publiqué mi solución de trabajo final a continuación.
Encontré la solución.
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);