Java 6 function working in command line, but not working on Oracle server (AES 256)

荒凉一梦 提交于 2020-12-15 07:20:37

问题


I have a Java 6 function below:

import java.net.*; 
import java.io.*; 
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;

import javax.xml.bind.DatatypeConverter;

public class decryptSEK {

  public static void main(String[] args) {
    String encryptedSek =  args[0];
    String appKey = args[1];
    byte[] appKey32b = DatatypeConverter.parseBase64Binary(appKey);
    String decryptedSek = decryptBySymmetricKey(encryptedSek, appKey32b);
    System.out.println(decryptedSek);
  }

  public static String decryptBySymmetricKey(String encryptedSek, byte[] appKey) {
    Key aesKey = new SecretKeySpec(appKey, "AES"); // converts bytes(32 byte random generated) to key
    try {
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); // encryption type = AES with padding PKCS5
      cipher.init(Cipher.DECRYPT_MODE, aesKey); // initiate decryption type with the key
      byte[] encryptedSekBytes = DatatypeConverter.parseBase64Binary(encryptedSek); //Base64.getDecoder().decode(encryptedSek); // decode the base64 encryptedSek to bytes
      byte[] decryptedSekBytes = cipher.doFinal(encryptedSekBytes); // decrypt the encryptedSek with the initialized cipher containing the key(Results in bytes)
      // String decryptedSek = Base64.getEncoder().encodeToString(decryptedSekBytes); // convert the decryptedSek(bytes) to Base64 StriNG
      String decryptedSek = DatatypeConverter.printBase64Binary(decryptedSekBytes);
      return decryptedSek; // return results in base64 string
    } catch(Exception e) {
      return "Exception; "+e;
    }
  }
}

When I build the above as class file and then run java -classpath . decryptSEK it works well and the output is as expected. I installed JCE for Java 6, so it works well.

But when I convert this into an Oracle program to run on server like below:

--DECRYPT SEK
create or replace JAVA SOURCE NAMED decryptSEK AS
import java.net.*; 
import java.io.*; 
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.xml.bind.DatatypeConverter;

public class decryptSEK {

  public static void main(String[] args) {
    String encryptedSek =  args[0];
    String appKey = args[1];
    byte[] appKey32b = DatatypeConverter.parseBase64Binary(appKey);
    String decryptedSek = decryptBySymmetricKey(encryptedSek, appKey32b);
    System.out.println(decryptedSek);
  }
public static String decryptSEKcall(String encryptedSek,String appKey)
{
    byte[] appKey32b = DatatypeConverter.parseBase64Binary(appKey);
    String decryptedSek = decryptBySymmetricKey(encryptedSek, appKey32b);
    System.out.println(decryptedSek);
    return decryptedSek;
}

public static String decryptBySymmetricKey(String encryptedSek, byte[] appKey) {
    Key aesKey = new SecretKeySpec(appKey, "AES"); 
    try {
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 
      cipher.init(Cipher.DECRYPT_MODE, aesKey); 
      byte[] encryptedSekBytes = DatatypeConverter.parseBase64Binary(encryptedSek); 
      byte[] decryptedSekBytes = cipher.doFinal(encryptedSekBytes);
      String decryptedSek = DatatypeConverter.printBase64Binary(decryptedSekBytes);
      return decryptedSek; 
    } catch(Exception e) {
      return "Exception; "+e;
    }
  }
}

/
 CREATE OR REPLACE FUNCTION decryptSEK_func(P_ENCRYPTSEK VARCHAR2,P_APPKEY VARCHAR2)
 RETURN VARCHAR2 AS
    LANGUAGE JAVA NAME 'decryptSEK2.decryptSEKcall( java.lang.String,java.lang.String ) 
    return java.lang.String';
    
    select decryptSEK_func( 's8U+CjS8zKEmwmpCs7HnmTYKpx6rMwEdXVk/g8fNBhVMzKlFxkA1WemvUX00evh8',
    'SpRstt3iYywGQlI8U8SQfOA3jajkZpJGjlI4sPeVk7A=')encryptsek from dual;

It throws the following error:

Exception: java.security.InvalidKeyException: Illegal key size or default parameters

I have installed the JCE extension files and it seems to work on command prompt, but not when I change it to Oracle. Where I am going wrong?


回答1:


Instead of creating your own Java code to do encryption, I would highly recommend using the encryption functionality available in the DBMS_CRYPTO package. It does support AES/ECB/PKCS5Padding encryption, you will just need to set the proper "type" when calling the encrypt/decrypt functions. Below is the same example from the documentation but with the encryption type modified to what you are using in your Java code.

DECLARE
    input_string      VARCHAR2 (200) := 'Secret Message';
    output_string     VARCHAR2 (200);
    encrypted_raw     RAW (2000);              -- stores encrypted binary text
    decrypted_raw     RAW (2000);              -- stores decrypted binary text
    num_key_bytes     NUMBER := 256 / 8;       -- key length 256 bits (32 bytes)
    key_bytes_raw     RAW (32);                -- stores 256-bit encryption key
    encryption_type   PLS_INTEGER
        :=                                     -- total encryption type
           DBMS_CRYPTO.ENCRYPT_AES256 + DBMS_CRYPTO.CHAIN_ECB + DBMS_CRYPTO.PAD_PKCS5;
    iv_raw            RAW (16);
BEGIN
    DBMS_OUTPUT.PUT_LINE ('Original string: ' || input_string);
    key_bytes_raw := DBMS_CRYPTO.RANDOMBYTES (num_key_bytes);
    iv_raw := DBMS_CRYPTO.RANDOMBYTES (16);
    encrypted_raw :=
        DBMS_CRYPTO.ENCRYPT (src   => UTL_I18N.STRING_TO_RAW (input_string, 'AL32UTF8'),
                             typ   => encryption_type,
                             key   => key_bytes_raw,
                             iv    => iv_raw);
    -- The encrypted value "encrypted_raw" can be used here

    decrypted_raw :=
        DBMS_CRYPTO.DECRYPT (src   => encrypted_raw,
                             typ   => encryption_type,
                             key   => key_bytes_raw,
                             iv    => iv_raw);
    output_string := UTL_I18N.RAW_TO_CHAR (decrypted_raw, 'AL32UTF8');

    DBMS_OUTPUT.PUT_LINE ('Decrypted string: ' || output_string);
END;
/


来源:https://stackoverflow.com/questions/64765725/java-6-function-working-in-command-line-but-not-working-on-oracle-server-aes-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!