oracle-11g – 在Oracle pl / sql中复制或调用java加密函数

我试图复制Oracle DB中java中存在的加密/解密方法,以便在Java中加密的数据可以通过Oracle Function解密.

以下是java代码:

package com.encr;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class EncrUtil 
{
private static Cipher cipher = null;

public static void aesInit(String inKey) throws Exception 
{
    String methodName = "aesInit";
    try
    {

        byte[] inkeyBytes = inKey.getBytes("utf-8");
        System.out.println("inkeyBytes="+inkeyBytes.toString());
        final SecretKeySpec clientkey = new SecretKeySpec(inkeyBytes, "AES");
        cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        final IvParameterSpec iv = new IvParameterSpec(new byte[32]);
        cipher.init(Cipher.ENCRYPT_MODE,clientkey,iv);
    }
    catch (NoSuchAlgorithmException e) {
        throw new Exception("NoSuchAlgorithmException", e);
    } catch (NoSuchPaddingException e) {

        throw new Exception("NoSuchPaddingException", e);

    }
}

public static String encrypt(String inData,String inKey)
{
    String methodName = "encrypt";
    String strCipherText = null;
    try
    {
        if ( null != inData && null != inKey)
        {
            if(EncrUtil.cipher == null){
                EncrUtil.aesInit(inKey);
            }
            byte[] byteDataToEncrypt = inData.getBytes("utf-8");
            System.out.println(byteDataToEncrypt.toString());
            byte[] byteCipherText = cipher.doFinal(byteDataToEncrypt); 
            System.out.println(byteCipherText.toString());
            strCipherText = new BASE64Encoder().encode(byteCipherText);
        }

    }
    catch (Exception e) {
        String sErrMsg = "Text to be encrypted: " + inData;
        sErrMsg = new StringBuffer(methodName).append( sErrMsg) .append( "  Message: ") .append(e.getMessage()).toString();
        strCipherText = sErrMsg;

    }
    return strCipherText;

}

public static String decrypt(String inData,String inKey)
{
    String methodName = "decrypt";
    String strDecryptedText = null;
    try
    {

        byte[] inkeyBytes = inKey.getBytes("utf-8");
        final SecretKeySpec clientkey = new SecretKeySpec(inkeyBytes, "AES");
        cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        final IvParameterSpec iv = new IvParameterSpec(new byte[16]);
        cipher.init(Cipher.DECRYPT_MODE,clientkey,iv);
        byte[] decodedData = new BASE64Decoder().decodeBuffer(inData);
        byte[] byteDecryptedText = cipher.doFinal(decodedData);
        strDecryptedText = new String(byteDecryptedText);

    }
    catch (Exception e) {
        String sErrMsg = "Text to be decrypted: " + inData;
        sErrMsg = new StringBuffer(methodName).append(sErrMsg) .append( "Message:") .append(e.getMessage()).toString();
        strDecryptedText = sErrMsg;
    } 

    return strDecryptedText;

}

public static void main(String[] args) 
{
    String inKey= "84hf763bht096hnf";
    String inData= "Vikram";
    System.out.println("Word to be encrypted is "+inData);
    String encrypted = EncrUtil.encrypt(inData,inKey);
    System.out.println("Encrpted word is"+encrypted);

}
}

我尝试复制的Oracle Pl / sql函数是

CREATE OR REPLACE PACKAGE BODY SYS.enc_dec
AS
encryption_type    PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_AES
                                 + DBMS_CRYPTO.CHAIN_CBC
                                 + DBMS_CRYPTO.PAD_PKCS5;
encryption_key     RAW (32) := UTL_I18N.STRING_TO_RAW ('84hf763bht096hnf', 'AL32UTF8');
 FUNCTION encrypt (p_plainText VARCHAR2) RETURN RAW DETERMINISTIC
 IS
    encrypted_raw      RAW (2000);
 BEGIN
 DBMS_OUTPUT.PUT_LINE(UTL_RAW.CAST_TO_VARCHAR2(encryption_key));
    encrypted_raw := DBMS_CRYPTO.ENCRYPT
    (
       --src => UTL_RAW.CAST_TO_RAW (p_plainText),
       src =>UTL_I18N.STRING_TO_RAW (p_plainText,'AL32UTF8'),
       typ => encryption_type,
       key => encryption_key
    );
   RETURN encrypted_raw;
 EXCEPTION
  WHEN OTHERS THEN
  DBMS_OUTPUT.PUT_LINE(SUBSTR(SQLERRM, 1, 100));
 END encrypt;
 FUNCTION decrypt (p_encryptedText RAW) RETURN VARCHAR2 DETERMINISTIC
 IS
    decrypted_raw      RAW (2000);
 BEGIN
    decrypted_raw := DBMS_CRYPTO.DECRYPT
    (
        src => p_encryptedText,
        typ => encryption_type,
        key => encryption_key
    );
    RETURN (UTL_I18N.RAW_TO_CHAR(decrypted_raw,'AL16UTF8'));
 EXCEPTION
  WHEN OTHERS THEN
  DBMS_OUTPUT.PUT_LINE(SUBSTR(SQLERRM, 1, 100));
 END decrypt;
END;

上述代码完成的加密与java中的加密不同
请告诉我在oracle函数中出错的地方或
请告诉我如何在oracle中添加java方法,在教程中我找不到如何在oracle中包含java的导入.

解决方法:

我能够将Java代码移动到Oracle.我正在为面临类似问题的人写这篇文章.

>登录到通过Putty安装Oracle数据库的服务器(如果是windows,则为命令提示符)
>使用WinSCP将Java文件放在服务器中.
>使用命令查找oracle home中的Java编译器

find / -name javac

>使用Oracle的Java编译器编译Java文件作为数据库使用的Java版本,并且通常使用的Java版本将不同

$ORACLE_HOME/jdk/bin/javac /home/vikram/EncrUtil.java

注意:可以将.cl​​ass或.jar文件直接加载到数据库中,而不是在数据库服务器上进行编译.但请确保使用与数据库使用的相同版本的Java.

找到oracle使用的java版本

$ORACLE_HOME/jdk/bin/java -version
java version "1.5.0_17"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_17-b03)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_17-b03, mixed mode)

>如果未设置,则设置ORACLE_HOME

export ORACLE_HOME=/database/ora11gr2/product/11.2.0/dbhome_1/

>在路径中添加loadjava的目录(即数据库的bin目录)

export PATH=$PATH:$ORACLE_HOME/bin

注意:如果找不到类的异常,请通过“loadjava”检查路径是否正确设置或是否定义了变量未定义那些
>将类加载到数据库中

loadjava -user <user>/<password>@xxx.xxx.xxx.xxxx:1521:<instance> \
         -thin –resolve /home/vikram/ EncrUtil.class

> -resolve用于在加载到数据库之前解析.class文件,因为它易于调试Java外部数据库.
> -thin用于瘦客户端

>加载类后,在其上创建一个包装函数,以便可以在数据库中使用它

CREATE OR REPLACE FUNCTION TEST_DECRYPTOR(indata IN VARCHAR2)
RETURN VARCHAR2 AS
LANGUAGE JAVA NAME ' EncrUtil. decrypt (java.lang.String) return java.lang.String';
CREATE OR REPLACE FUNCTION TEST_ENCRYPTOR (indata IN VARCHAR2)
RETURN VARCHAR2 AS
LANGUAGE JAVA NAME ' EncrUtil. encrypt (java.lang.String) return java.lang.String';

>然后可以像使用任何其他Oracle函数一样使用此函数:

SELECT TEST_ENCRYPTOR('Vikram') FROM DUAL;
上一篇:不安装Oracle客户端,用PLSQL连接Oracle


下一篇:如何从Oracle SQL脚本中分离出各个sql语句,以便从java代码执行