¿Por qué el cifrado RSA en Java produce un texto cifrado de diferente longitud que C #?

yamerali:

Estoy AESencriptando algo de texto usando una clave generada aleatoriamente y luego RSAencriptando esa clave con una clave privada para poder subirla a una base de datos.

Las RSAclaves se generan usando KeyPairGeneratorin Javay se guardan como un archivo. Las claves se leen usando File.ReadAllBytes().

Cuando hago esto en Java todo funciona perfectamente y la clave encriptada es siempre 172 bytes, pero cuando lo hago en C#la clave encriptada es siempre 844 bytes. Estoy bastante seguro de que el texto se está cifrando correctamente AES, pero algo va mal con el RSAcifrado.

He comprobado los tamaños de clave en Java y C # y siempre coinciden. Literalmente, la única diferencia que puedo ver es la longitud del texto cifrado encriptado RSA, que hace que los datos sean inutilizables. Creo que tiene algo que ver con el acolchado, pero no sé cómo arreglarlo.

Java

public String encryptText(String msg, PrivateKey key) 
            throws NoSuchAlgorithmException, NoSuchPaddingException,
            UnsupportedEncodingException, IllegalBlockSizeException, 
            BadPaddingException, InvalidKeyException {

        KeyGenerator generator;   
        this.cipher.init(Cipher.ENCRYPT_MODE, key); //cipher is initialized earlier with this.cipher = Cipher.getInstance("RSA");

            try {
                generator = KeyGenerator.getInstance(AES);
                generator.init(128); // The AES key size in number of bits
                SecretKey secKey = generator.generateKey();

                Cipher aesCipher = Cipher.getInstance(AES);
                aesCipher.init(Cipher.ENCRYPT_MODE, secKey);

                String encText = Base64.getEncoder().encodeToString(aesCipher.doFinal(msg.getBytes("UTF-8")));
                String encKey = Base64.getEncoder().encodeToString(cipher.doFinal(secKey.getEncoded()));

                return "(" + encText + ")" + encKey;                
            } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        return null;
    }

C#

public String EncryptText(byte[] privateKeyBytes, string msg)
        {
            try
            {
                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
                RSAParameters RSAKeyInfo = RSA.ExportParameters(false);

                RSAKeyInfo.Modulus = privateKeyBytes;
                RSA.ImportParameters(RSAKeyInfo);

                RijndaelManaged aes = new RijndaelManaged();
                aes.BlockSize = 128;
                aes.KeySize = 128;
                aes.Mode = CipherMode.ECB;
                byte[] keyGenerated = aes.Key;

                string keyStr = Convert.ToBase64String(keyGenerated);
                byte[] keyArr = Convert.FromBase64String(keyStr);
                byte[] KeyArrBytes16Value = new byte[16];
                Array.Copy(keyArr, KeyArrBytes16Value, 16);

                aes.Key = KeyArrBytes16Value;

                ICryptoTransform encrypto = aes.CreateEncryptor();

                byte[] plainTextByte = ASCIIEncoding.UTF8.GetBytes(msg);
                byte[] CipherText = encrypto.TransformFinalBlock(plainTextByte, 0, plainTextByte.Length);

                string encText = Convert.ToBase64String(CipherText);
                string encKey = Convert.ToBase64String(RSA.Encrypt(aes.Key, true));

                return "(" + encText + ")" + encKey;

            }
            catch (CryptographicException e)
            {
                Console.WriteLine("FAILED: " + e.Message);
            }

            return null;
        }

ACTUALIZAR
Gracias a Henno por señalar que el problema estaba en cómo estaba leyendo la clave. Terminé usando Bouncy Castle para manejar el cifrado RSA en C #. También cambié mi código Java para cifrarlo con la clave pública en lugar de la clave privada.

Nuevo C #

public String EncryptText(byte[] keyBytes, string msg)
        {
            try
            {
                AsymmetricKeyParameter asymmetricKeyParameter = PublicKeyFactory.CreateKey(keyBytes);
                RsaKeyParameters rsaKeyParameters = (RsaKeyParameters)asymmetricKeyParameter;
                RSAParameters rsaParameters = new RSAParameters();
                rsaParameters.Modulus = rsaKeyParameters.Modulus.ToByteArrayUnsigned();
                rsaParameters.Exponent = rsaKeyParameters.Exponent.ToByteArrayUnsigned();
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                rsa.ImportParameters(rsaParameters);

                RijndaelManaged aes = new RijndaelManaged();
                aes.BlockSize = 128;
                aes.KeySize = 128;
                aes.Mode = CipherMode.ECB;
                byte[] keyGenerated = aes.Key;

                string keyStr = Convert.ToBase64String(keyGenerated);
                byte[] keyArr = Convert.FromBase64String(keyStr);
                byte[] KeyArrBytes16Value = new byte[16];
                Array.Copy(keyArr, KeyArrBytes16Value, 16);

                aes.Key = KeyArrBytes16Value;

                ICryptoTransform encrypto = aes.CreateEncryptor();

                byte[] plainTextByte = ASCIIEncoding.UTF8.GetBytes(msg);
                byte[] CipherText = encrypto.TransformFinalBlock(plainTextByte, 0, plainTextByte.Length);

                string encText = Convert.ToBase64String(CipherText);
                string encKey = Convert.ToBase64String(rsa.Encrypt(aes.Key, false));

                return "(" + encText + ")" + encKey;

            }
            catch (CryptographicException e)
            {
                Console.WriteLine("FAILED: " + e.Message);
            }

            return null;
        }
Henno Brandsma:

Lo que parece salir mal es que lee en el "archivo de clave privada" guardado en C #, presumiblemente en la variable privateKeyBytes(pero su código está incompleto, supongo) y luego lo hace RSAKeyInfo.Modulus = privateKeyBytes, lo cual es extraño y criptográficamente inverosímil. También debe crear una instancia de algún tipo de clase RSA en C #, según los bytes que lee, que es lo que creo que está tratando de hacer al principio del código C # (primeras cuatro líneas). Creo que debería haber otra API para eso, buscando en los documentos:

RSA.ImportParameters(RSAKeyInfo)y luego quizás establezca RSAKeyInfo a partir de esos bytes, pero no es el módulo. La lectura en bytes debe ser el formato PKCS1 o algo similar, puede estar codificado en base64 en un archivo, o sin formato, etc. Tendría que ver qué formato usa Java para exportar claves completas al disco.

Usas los bytes sin procesar que lees desde el archivo como módulo, lo que seguramente dará problemas y da una "clave" que no es válida y también demasiado grande.

Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.

En caso de infracción, por favor [email protected] Eliminar

Editado en
0

Déjame decir algunas palabras

0Comentarios
Iniciar sesiónRevisión de participación posterior

Artículos relacionados

El cifrado RSA en java y python da un resultado de cifrado diferente

Cómo cambiar un algoritmo de cifrado de bloque texto cifrado y longitud de texto plano

La longitud del valor cifrado utilizando la API de Google KMS en C # es diferente de la longitud del texto cifrado generado directamente desde la API en cartero

La longitud del valor cifrado utilizando la API de Google KMS en C # es diferente de la longitud del texto cifrado generado directamente desde la API en cartero

¿Por qué el cifrado ECIES da un valor diferente cada vez que se llama?

El cifrado Java / Kotlin AES-128-CBC produce un resultado diferente al de OpenSSL

Cifrado DES en Java vs .NET: ¿por qué diferente?

Cifrado RSA determinista en Golang: cómo obtener el mismo resultado para un mensaje determinado en varios tiempos de cifrado

Cómo descifrar un texto cifrado en Go que está cifrado en vuejs usando el paquete aes-js

En el cifrado RSA, ¿funciona en Java pero no funciona con el cifrado desde c #?

Agregar un cifrado césar en el chat de java

El cifrado RSA bloque por bloque produce una salida en blanco para archivos de más de 1 kb

Es el texto cifrado dado mediante el cifrado de un archivo con CipherInputStream la misma longitud, entonces el propio archivo

Error de relleno al usar el cifrado RSA en C # y el descifrado en Java

¿Por qué el resultado de cifrado DES ejecutado en diferentes Java desde ejecutado en PHP?

¿Por qué siempre obtuve un resultado des-ecb incorrecto en el cifrado nativo de nodejs?

Cifrado RSA determinista en Java

¿Por qué hay una diferencia en el texto cifrado generado entre las bibliotecas OpenSSL EVP C y Python?

Los números de cifrado RSA no funcionan, ¿por qué?

¿Qué es el certificado en el contexto de RSA y cifrado asimétrico?

¿Por qué mi cifrado RSA de Java me da una excepción aritmética?

¿Cómo replicar el cifrado de Java en PHP?

¿Cómo descifro el texto que ya está cifrado en el pasado utilizando Java AES 256 Decryption?

Obtener el tamaño de bloque de un cifrado RSA

Estoy tratando de cifrar un archivo de texto usando el cifrado vigenere y xor en c ++ pero no cifrará el archivo

¿Por qué mis bytes son diferentes en la cuarta ronda de este puerto C # de un algoritmo de cifrado?

Modificación de texto cifrado encriptado rsa

El cifrado TripleDES resulta diferente en C # y Node JS

¿Cómo cifrar un mensaje de más de 53 bytes usando el cifrado RSA?

TOP Lista

CalienteEtiquetas

Archivo