2017-12-07 7 views
0

Rijndaelの.Net暗号化ファイルと.Net RSA XML Keyが与えられ、Javaで解読するように求められました。Rijndaelを使用して暗号化されたjavaのファイルを復号化する際にエラーが発生しました

私に提供される鍵は256ビットです。

私はRSA XMLファイルを解析し、公開鍵をJavaで生成しました。私は、生成されたキーを使用して解読しようとしましたが、例外が発生しましたIllegal Key Size、私は私のJavaコードで何か間違っていると思います。

私のコードに問題がないかどうかを確認するのに手伝ってください。

の.Net暗号コード:

public static void EncryptFile(string fileIn, string fileOut, 
            string publicKeyName, string publicKeyFile) 
    { 
     try 
     { 
      // Read the public key from key file 
      StreamReader sr = new StreamReader(publicKeyFile); 
      string strKeyText = sr.ReadToEnd(); 
      sr.Close(); 

      //Initialize Key container and Crypto service provider 
      RSACryptoServiceProvider rsa; 
      CspParameters cspp = new CspParameters(); 
      cspp.KeyContainerName = publicKeyName; 
      rsa = new RSACryptoServiceProvider(cspp); 
      rsa.FromXmlString(strKeyText); 
      rsa.PersistKeyInCsp = true; 

      // Create instance of Rijndael for 
      // symetric encryption of the data. 
      RijndaelManaged alg = new RijndaelManaged(); 
      // Key size is set to 256 for strong encryption 
      alg.KeySize = 256; 
      alg.BlockSize = 256; 
      // Cipher Mode is set to CBC to process the file in chunks 
      alg.Mode = CipherMode.CBC; 
      // Set padding mode to process the last block of the file 
      alg.Padding = PaddingMode.ISO10126; 

      ICryptoTransform transform = alg.CreateEncryptor(); 

      // Use RSACryptoServiceProvider to 
      // enrypt the Rijndael key. 
      byte[] KeyEncrypted = rsa.Encrypt(alg.Key, false); 

      // Create byte arrays to contain 
      // the length values of the key and IV. 
      int intKeyLength = KeyEncrypted.Length; 
      byte[] LenK = BitConverter.GetBytes(intKeyLength); 
      int intIVLength = alg.IV.Length; 
      byte[] LenIV = BitConverter.GetBytes(intIVLength); 


      using (FileStream fsOut = new FileStream(fileOut, FileMode.Create)) 
      { 
       // Write the following to the FileStream 
       // for the encrypted file (fsOut): 
       // - length of the key 
       // - length of the IV 
       // - ecrypted key 
       // - the IV 
       // - the encrypted cipher content 
       fsOut.Write(LenK, 0, 4); 
       fsOut.Write(LenIV, 0, 4); 
       fsOut.Write(KeyEncrypted, 0, intKeyLength); 
       fsOut.Write(alg.IV, 0, intIVLength); 

       // Now write the cipher text using 
       // a CryptoStream for encrypting. 
       using (CryptoStream cs = new CryptoStream(fsOut, transform, CryptoStreamMode.Write)) 
       { 
        // intBlockSizeBytes can be any arbitrary size. 
        int intBlockSizeBytes = alg.BlockSize/8; 
        byte[] DataBytes = new byte[intBlockSizeBytes]; 
        int intBytesRead = 0; 

        using (FileStream fsIn = new FileStream(fileIn, FileMode.Open)) 
        { 
         // By encrypting a chunk at 
         // a time, you can save memory 
         // and accommodate large files. 
         int intCount; 
         int intOffset = 0; 

         do 
         { 
          // if last block size is less than encryption chunk size 
          // use the last block size and padding character is used 
          // for remaining bytes 
          if (intBlockSizeBytes > (fsIn.Length - fsIn.Position)) 
          { 
           intBlockSizeBytes = ((int)(fsIn.Length - fsIn.Position)); 
           DataBytes = new byte[intBlockSizeBytes]; 
          } 
          // read data bytes 
          intCount = fsIn.Read(DataBytes, 0, intBlockSizeBytes); 
          intOffset += intCount; 
          // write it into crypto stream 
          cs.Write(DataBytes, 0, intCount); 
          intBytesRead += intBlockSizeBytes; 
         } while (intCount > 0); 
         // close input file 
         fsIn.Close(); 
        } 
        // close crypto stream 
        cs.FlushFinalBlock(); 
        cs.Close(); 
       } 
       // close output file 
       fsOut.Close(); 
      } 
     } 
     catch 
     { 
      throw; 
     } 
    } 

Javaコード私はそれを復号化するために書いた:

byte[] expBytes = Base64.decodeBase64(pkey.getExponentEle().trim()); 
    byte[] modBytes = Base64.decodeBase64(pkey.getModulusEle().trim()); 
    byte[] dBytes = Base64.decodeBase64(pkey.getdEle().trim()); 

    BigInteger modules = new BigInteger(1, modBytes); 
    BigInteger exponent = new BigInteger(1, expBytes); 
    BigInteger d = new BigInteger(1, dBytes); 

    KeyFactory factory = KeyFactory.getInstance("RSA"); 
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 

    RSAPublicKeySpec pubSpec = new RSAPublicKeySpec(modules, exponent); 
    PublicKey pubKey = factory.generatePublic(pubSpec); 

    final byte[] keyData = Arrays.copyOf(pubKey.getEncoded(), 256 
      /Byte.SIZE); 
     final byte[] ivBytes = Arrays.copyOf(keyData, cipher.getBlockSize()); 
     AlgorithmParameterSpec paramSpec = new IvParameterSpec(ivBytes); 

     cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyData, "AES"), paramSpec); 
    byte[] decrypted = cipher.doFinal(encrypted); 
    System.out.println("decrypted: " + new String(decrypted)); 

私はcipher.init(Cipher.DECRYPT_MODE, pubKey);に暗号初期を変更した場合は、その後、私はエラーにInvalid AES key length: 162 bytes

を取得しています

答えて

0

あなたは公開鍵を間違った方法で使用しています。あなたは本当にC#プログラムの仕組みを理解していますか?どんなパラメータを使用していますか?

あなたはAES鍵として公開鍵ビットを使用しています(実際には162バイトをどのように取得するのかは分かりませんが)。

これは「ハイブリッド暗号化」の例です。データ自体はランダムなAESキーで暗号化されています(これは256ビットと主張しています)、AESキー(この場合はIV)もRSA公開鍵で暗号化されていますキー。 Javaには多くのものがありますexamples how to do that

AESキーを復号化する場合でも、暗号化に使用するパラメータ(RSA/ECB/PKCS5Padding、RSA-AOEP、...)はXML内にある必要があります。

パラメータにコミットする - あなたはPKCS5Paddingを使用していますが、.NETコードをチェックしてください、それは異なっています

関連する問題