[英]Java 6 function working in command line, but not working on Oracle server (AES 256)
I have a Java 6 function below:我在下面有一个 Java 6 函数:
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
当我将上述内容构建为类文件然后运行
java -classpath . decryptSEK
java -classpath . decryptSEK
it works well and the output is as expected. java -classpath . decryptSEK
它运行良好,输出符合预期。 I installed JCE for Java 6, so it works well.我为 Java 6 安装了 JCE,所以它运行良好。
But when I convert this into an Oracle program to run on server like below:但是当我将其转换为 Oracle 程序以在服务器上运行时,如下所示:
--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.我已经安装了 JCE 扩展文件,它似乎在命令提示符下工作,但当我将其更改为 Oracle 时则无法工作。 Where I am going wrong?
我哪里出错了?
Instead of creating your own Java code to do encryption, I would highly recommend using the encryption functionality available in the DBMS_CRYPTO package.我强烈建议您使用DBMS_CRYPTO包中提供的加密功能,而不是创建您自己的 Java 代码来进行加密。 It does support
AES/ECB/PKCS5Padding
encryption, you will just need to set the proper "type" when calling the encrypt/decrypt functions.它确实支持
AES/ECB/PKCS5Padding
加密,您只需要在调用加密/解密函数时设置正确的“类型”。 Below is the same example from the documentation but with the encryption type modified to what you are using in your Java code.下面是文档中的相同示例,但加密类型已修改为您在 Java 代码中使用的加密类型。
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;
/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.