【问题标题】:AES Encryption Java/plsqlAES 加密 Java/plsql
【发布时间】:2020-05-08 18:23:21
【问题描述】:

我需要在 Java 和 plsql(Oracle 10g 的 DBMS_CRYPTO)上实现相同的加密/解密应用程序。

这两种实现都工作正常,但这里的 pb 是我得到不同的输出来加密相同的纯文本。 在用于加密/解密过程(Java 和 PLSQL)的代码下方。

我对 DBMS_CRYPTO 和 Java 使用了相同的加密算法“AES/CBC/PKCS5Padding”。这里的问题是我得到不同的输出来加密相同的纯文本。

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.*;
import org.apache.commons.codec.binary.Hex;

public class AESencrp {

    private static final String ALGO = "AES/CBC/PKCS5Padding";


    private static final byte[] keyValue = "MyEncryptionKey1".getBytes();
    private static Key key;
    private static Cipher decryptor;
    private static Cipher encryptor;


    public static  void init() throws Exception 
    {

        key = generateKey();
        encryptor = Cipher.getInstance(ALGO);
        IvParameterSpec iv = new IvParameterSpec(Hex.decodeHex("12345678901234567890123456789012".toCharArray()));   
        decryptor=Cipher.getInstance(ALGO);
        encryptor.init(Cipher.ENCRYPT_MODE, key,iv);
        decryptor.init(Cipher.DECRYPT_MODE, key,iv);
    }




public static String encrypt(String Data) throws Exception {
        byte[] encVal = encryptor.doFinal(Data.getBytes());
        String encryptedValue = new BASE64Encoder().encode(encVal);
        return encryptedValue;
    }

 public static String decrypt(String encryptedData) throws Exception {

        byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
        byte[] decValue = decryptor.doFinal(decordedValue);
        String decryptedValue = new String(decValue);
        return decryptedValue;
    }

 private static Key generateKey() throws Exception {
        if (key==null)
        key = new SecretKeySpec(keyValue, "AES");
        return key;
}

  public static void main(String[] args) throws Exception {

        init();
        String password = "mypassword";
        String passwordEnc = AESencrp.encrypt(password);
        String passwordDec = AESencrp.decrypt(passwordEnc);

        System.out.println("Plain Text : " + password);
        System.out.println("Encrypted Text : " + passwordEnc);
        System.out.println("Decrypted Text : " + passwordDec);
    }
    }
  • Java 执行:

纯文本:我的密码

加密文本:+pvG30k4/KFkeim47tslFQ==

解密文本:我的密码

CREATE OR REPLACE PACKAGE BODY SYSADM.enc_dec
AS
     encryption_type    PLS_INTEGER :=DBMS_CRYPTO.AES_CBC_PKCS5; 
     encryption_key     RAW (32) := UTL_RAW.cast_to_raw('MyEncryptionKey1');


     FUNCTION encrypt (p_plainText VARCHAR2) RETURN RAW DETERMINISTIC
     IS
        encrypted_raw      RAW (2000);
     BEGIN
        encrypted_raw := DBMS_CRYPTO.ENCRYPT
        (
           src => UTL_RAW.CAST_TO_RAW (p_plainText),
           typ => encryption_type,
           key => encryption_key,
           iv => hextoraw('12345678901234567890123456789012') 
        );
       RETURN encrypted_raw;
     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,
            iv => hextoraw('12345678901234567890123456789012') 
        );
        RETURN (UTL_RAW.CAST_TO_VARCHAR2 (decrypted_raw));
     END decrypt;
END;
/
  • PlSQL 执行:

选择从双重加密的enc_dec.encrypt('mypassword');

FA9BC6DF4938FCA1647A29B8EEDB2515

选择从双重解密的enc_dec.decrypt(enc_dec.encrypt('mypassword'));

我的密码

  • Java -->+pvG30k4/KFkeim47tslFQ==

  • PLSQL -->FA9BC6DF4938FCA1647A29B8EEDB2515

您能否告知为什么我们在两个加密输出之间存在这种差异? AES 加密是否存在编程语言依赖项??

【问题讨论】:

    标签: java encryption plsql aes


    【解决方案1】:

    +pvG30k4/KFkeim47tslFQ== 采用 Base64 表示,而
    FA9BC6DF4938FCA1647A29B8EEDB2515 采用 HEX 表示,但两个字符串表示相同的值。

    确定您将使用的单一表示,并将其中一个输出转换为它。

    【讨论】:

      【解决方案2】:

      如果有人对第一篇基于 Java 代码的 PL/SQL 完整代码感兴趣。

      加密功能:

      CREATE OR REPLACE FUNCTION F_ENCRYPT (p_plainText VARCHAR2)
         RETURN VARCHAR2
      AS
         encryption_type    PLS_INTEGER :=DBMS_CRYPTO.AES_CBC_PKCS5; 
         encryption_key     RAW (32) := UTL_RAW.cast_to_raw('MyEncryptionKey1');
         encrypted_raw      RAW (2000);
      BEGIN
         encrypted_raw := DBMS_CRYPTO.ENCRYPT
             (
                 src => UTL_RAW.CAST_TO_RAW (p_plainText),
                 typ => encryption_type,
                 key => encryption_key,
                 iv => hextoraw('12345678901234567890123456789012') 
             ); 
             RETURN UTL_RAW.CAST_TO_VARCHAR2 (UTL_ENCODE.base64_encode (encrypted_raw));
      END;
      

      解密函数:

      CREATE OR REPLACE FUNCTION F_DECRYPT (p_input VARCHAR2)
         RETURN VARCHAR2
      AS
        encryption_type    PLS_INTEGER :=DBMS_CRYPTO.AES_CBC_PKCS5; 
        encryption_key     RAW (32) := UTL_RAW.cast_to_raw('MyEncryptionKey1');
        decrypted_raw      RAW (2000);
      BEGIN
        decrypted_raw := DBMS_CRYPTO.DECRYPT
           (
               src => UTL_ENCODE.base64_decode (UTL_RAW.CAST_TO_RAW (p_input)),
               typ => encryption_type,
               key => encryption_key,
               iv => hextoraw('12345678901234567890123456789012') 
           );
           RETURN (UTL_RAW.CAST_TO_VARCHAR2 (decrypted_raw));
      END;
      

      验证:

      SELECT 'mypassword' INPUT, 
          F_ENCRYPT('mypassword') ENCRYPTED_RESULT,
          F_DECRYPT(F_ENCRYPT('mypassword')) DECRYPT_RESULT 
      FROM DUAL;
      

      验证输出:

      "INPUT"       "ENCRYPTED_RESULT"          "DECRYPT_RESULT"
      "mypassword"  "+pvG30k4/KFkeim47tslFQ=="  "mypassword"
      

      【讨论】:

        【解决方案3】:

        在 oracle plsql 中使用加密/解密

        create or replace PACKAGE BODY          "PKG_LOGI_PWD_REG" 
        as
          FUNCTION decrypt_val( p_val IN RAW ) RETURN VARCHAR2  
          IS
            l_decrypted RAW(32);
            l_decrypted_string VARCHAR2(32);
            L_USER  varchar2(32);
            L_CHARACTER_SET varchar2(10);
            L_STRING varchar2(32);
            L_KEY raw(250);
            L_ENCRYPTION_TYPE PLS_INTEGER;
          BEGIN
                L_KEY := UTL_I18N.STRING_TO_RAW
                                    ( data => '98345678901234567890123456789012',
                                      DST_CHARSET => 'AL32UTF8' );
                L_ENCRYPTION_TYPE := dbms_crypto.encrypt_aes256 
                                                + DBMS_CRYPTO.CHAIN_CBC 
                                                + DBMS_CRYPTO.PAD_PKCS5;
        
                l_decrypted := dbms_crypto.decrypt
                        ( SRC => P_VAL,
                          TYP => L_ENCRYPTION_TYPE,
                          key => L_KEY );
        
                l_decrypted_string := utl_i18n.raw_to_char
                            ( data => l_decrypted ,
                              src_charset => 'AL32UTF8' );
                RETURN l_decrypted_string;
        
          end DECRYPT_VAL;
        
          FUNCTION encrypt_val( p_val IN VARCHAR2 ) RETURN VARCHAR2
          is
            L_VAL RAW(32);
            L_ENCRYPTED raw(32);
            L_CHARACTER_SET varchar2(10);
            L_STRING varchar2(32);
            L_KEY RAW(250);
            L_ENCRYPTION_TYPE PLS_INTEGER;
          begin
        
        
            L_KEY := UTL_I18N.STRING_TO_RAW
                                ( data => '98345678901234567890123456789012',
                                  DST_CHARSET => 'AL32UTF8' );
            L_ENCRYPTION_TYPE := dbms_crypto.encrypt_aes256 
                                            + DBMS_CRYPTO.CHAIN_CBC 
                                            + DBMS_CRYPTO.PAD_PKCS5;
            L_VAL := utl_i18n.string_to_raw
                      ( data => p_val,
                        dst_charset => 'AL32UTF8' );
        
            L_ENCRYPTED := dbms_crypto.encrypt
                           ( SRC => L_VAL,
                             TYP => L_ENCRYPTION_TYPE,
                             key => L_KEY );
        
        
            return L_ENCRYPTED;
          EXCEPTION when OTHERS then
            RETURN SQLCODE||'-'||SQLERRM;
          end ENCRYPT_VAL;
        end PKG_LOGI_PWD_REG;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-06-05
          • 2012-03-28
          • 2012-06-01
          • 2017-05-31
          • 1970-01-01
          • 2013-04-19
          • 2019-10-27
          • 1970-01-01
          相关资源
          最近更新 更多