加解密,解密前使用16進制編碼轉換字節,加密後使用16進制編碼轉換。以下Java、Go都是針對Oracle進行匹配加解密的。DES加解密都是使用DES/CBC/ZeroPadding模式。
Oracle DES/CBC/ZeroPadding
加密方式CBC,填充方式使用0,偏移量0
--DES 加密
create or replace function des_encrypt(p_text varchar2, p_key varchar2)
return varchar2 is
v_text varchar2(2048);
v_enc varchar2(2048);
v_filllen pls_integer;
begin
--文本分組不足8位補充0
v_filllen := ceil(lengthb(p_text) / 8) * 8 - lengthb(p_text);
v_text := p_text;
while (v_filllen > 0) loop
v_text := v_text || chr(0);
v_filllen := v_filllen - 1;
end loop;
--DES內置加密
dbms_obfuscation_toolkit.desencrypt(input_string => v_text,
key_string => p_key,
encrypted_string => v_enc);
return rawtohex(utl_raw.cast_to_raw(v_enc));
exception
when others then
return null;
end;
--DES 解密
create or replace function des_decrypt(p_text j varchar2, p_key varchar2)
return varchar2 is
v_text varchar2(2048);
v_enc varchar2(2048);
begin
--密文16進制轉換爲普通字符串
v_enc := utl_raw.cast_to_varchar2(hextoraw(p_text));
--內置des解密
dbms_obfuscation_toolkit.desdecrypt(input_string => v_enc,
key_string => p_key,
decrypted_string => v_text);
return rtrim(v_text, chr(0));
exception
when others then
return null;
end;
Java DES/CBC/ZeroPadding
加密方式CBC,填充方式使用0,偏移量0
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.io.UnsupportedEncodingException;
import java.security.Key;
/**
* @author zhuyuan 2019/6/1 10:47
*/
public class DESUtils {
private static final String SECRET_KEY_FACTORY_ALGORITHM = "DES";
/**
* 加密算法:DES
* 加密模式:CBC,每一組的加密模式與之前一組的加密進行強關聯。
* 位數不足填充模式:不要自動填充,填充由程序實現,使用0填充。
*/
private static final String CIPHER_ALGORITHM = "DES/CBC/NoPadding";
/**
* 密鑰
*/
private static final String DEFAULT_SECRET_KEY = "12345678";
/**
* 偏移量
*/
private static final byte[] SECRET_KEY_IV = {0, 0, 0, 0, 0, 0, 0, 0};
/**
* 分組長
*/
private final static int BLOCK_SIZE = 8;
/**
* 加密
*
* @param sourceData
* @return
*/
public static String encrypt(String sourceData) {
return encrypt(sourceData, DEFAULT_SECRET_KEY);
}
/**
* 加密
*
* @param sourceData
* @param secretKey
* @return
*/
public static String encrypt(String sourceData, String secretKey) {
return bytesToHexStr(encrypt(sourceData.getBytes(), secretKey));
}
/**
* 加密
*
* @param sourceData byte[]
* @param secretKey String
* @return byte[]
*/
public static byte[] encrypt(byte[] sourceData, String secretKey) {
try {
DESKeySpec desKey = new DESKeySpec(secretKey.getBytes());
// 創建一個密匙工廠,然後用它把DESKeySpec轉換成
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(SECRET_KEY_FACTORY_ALGORITHM);
Key key = keyFactory.generateSecret(desKey);
// Cipher對象實際完成加密操作
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// CBC迭代偏移
IvParameterSpec ips = new IvParameterSpec(SECRET_KEY_IV);
// 用密匙初始化Cipher對象
cipher.init(Cipher.ENCRYPT_MODE, key, ips);
// 現在,獲取數據並加密
// 正式執行加密操作
return cipher.doFinal(addPadding(sourceData));
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
}
Go DES/CBC/ZeroPadding
加密方式CBC,填充方式使用0,偏移量0
package main
import (
"strings"
"bytes"
"encoding/hex"
"crypto/des"
"crypto/cipher"
)
func main() {
text := DesEncrypt([]byte("NO爺"), []byte("12345678"))
println("加密結果:", strings.ToUpper(hex.EncodeToString(text)));
text2 := DesDecrypt(text, []byte("12345678"));
println("解密結果:", string(text2))
}
//加密
func DesEncrypt(origData, key []byte) []byte {
iv := []byte{0, 0, 0, 0, 0, 0, 0, 0}
block, err := des.NewCipher(key)
if err != nil {
return nil
}
origData = ZeroPadding(origData)
blockMode := cipher.NewCBCEncrypter(block, iv)
crypted := make([]byte, len(origData))
blockMode.CryptBlocks(crypted, origData)
return crypted
}
func ZeroPadding(in []byte) []byte {
length := len(in);
if (length % 8 == 0) {
return in;
} else {
blockCount := length / 8;
out := make([]byte, (blockCount + 1) * 8)
var i int;
for i = 0; i < length; i++ {
out[i] = in[i];
}
return out;
}
}
//解密
func DesDecrypt(crypted, key []byte) []byte {
iv := []byte{0, 0, 0, 0, 0, 0, 0, 0}
block, err := des.NewCipher(key)
if err != nil {
return nil
}
origData := make([]byte, len(crypted))
blockMode := cipher.NewCBCDecrypter(block, iv)
blockMode.CryptBlocks(origData, crypted)
return NullUnPadding(origData)
}
func NullUnPadding(in []byte) []byte {
return bytes.TrimRight(in, string([]byte{0}));
}