key, iv 自己随意设定
为了让结果可正常打印输入显示,都经过base64处理
* TripleDES.go
package auth
import (
"bytes"
"crypto/cipher"
"crypto/des"
"encoding/base64"
)
type TripleDES struct {
key string
iv string
}
// @ref: https://blog.csdn.net/xiaoxiao_haiyan/article/details/81320350
func (this *TripleDES) Encrypt(plain string) (string, error) {
key := []byte(this.key)
iv := []byte(this.iv)
block, err := des.NewTripleDESCipher(key)
if err != nil {
return "", err
}
input := []byte(plain)
// input = PKCS5Padding(input, block.BlockSize())
blockMode := cipher.NewOFB(block, iv)
crypted := make([]byte, len(input))
blockMode.XORKeyStream(crypted, input)
return base64.StdEncoding.EncodeToString(crypted), err
}
func (this *TripleDES) Decrypt(secret string) (string, error) {
key := []byte(this.key)
iv := []byte(this.iv)
crypted, err := base64.StdEncoding.DecodeString(secret)
if err != nil {
return "", err
}
block, err := des.NewTripleDESCipher(key)
if err != nil {
return "", err
}
blockMode := cipher.NewOFB(block, iv)
origData := make([]byte, len(crypted))
blockMode.XORKeyStream(origData, crypted)
// origData = PKCS5UnPadding(origData)
return string(origData), nil
}
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func PKCS5UnPadding(origData []byte) []byte {
length := len(origData)
// 去掉最后一个字节 unpadding 次
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
* TripleDES_test.go
package auth
import (
"strings"
"testing"
)
func TestTripleDES_Encrypt(t *testing.T) {
input := "11111"
key := "\x8a\xbe\x1e\x3f..."
iv := "\x8a\xbe\x1e\x3f\xab\xb0\x90\xe8"
des := TripleDES{key: key, iv: iv}
output, err := des.Encrypt(input)
if err != nil {
t.Errorf(err.Error())
}
t.Log(output)
if output != "VMtLmys=" {
t.Fail()
}
}
func TestTripleDES_Decrypt(t *testing.T) {
input := "FY8OxXQKh4I="
key := "\x8a\xbe\x1e\x3f..."
iv := "\x8a\xbe\x1e\x3f\xab\xb0\x90\xe8"
des := TripleDES{key: key, iv: iv}
output, err := des.Decrypt(input)
if err != nil {
t.Errorf(err.Error())
}
t.Log(output)
if strings.Compare(output, "putongj3") != 0 {
t.Fail()
}
}
参考文章: golang实现3DES加解密_xiaoxiao_haiyan的博客-CSDN博客_3des golang
Java版本
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.util.Base64;
public class TripleDES {
// private final String key = "ZMiKVoJmzlqFRylAg8IV0hjU";
// private final String iv = "ZMiKVoJm";
private byte[] bytesKey;
private byte[] bytesIv;
TripleDES(String key, String iv) {
this.bytesKey = key.getBytes();
this.bytesIv = iv.getBytes();
}
public String encrypt(String plain) {
byte[] result = null;
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
DESedeKeySpec desedeKeySpec = new DESedeKeySpec(bytesKey);
Key convertSecretKey = factory.generateSecret(desedeKeySpec);
//加密
Cipher cipher = Cipher.getInstance("DESede/OFB/NoPadding");
IvParameterSpec ips = new IvParameterSpec(bytesIv);
cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey, ips);
result = cipher.doFinal(plain.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return Base64.getEncoder().encodeToString(result);
}
public String decrypt(String crypted) {
byte[] cryptedBytes = Base64.getDecoder().decode(crypted);
String result = "";
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
DESedeKeySpec desedeKeySpec = new DESedeKeySpec(bytesKey);
Key convertSecretKey = factory.generateSecret(desedeKeySpec);
Cipher cipher = Cipher.getInstance("DESede/OFB/NoPadding");
IvParameterSpec ips = new IvParameterSpec(bytesIv);
cipher.init(Cipher.DECRYPT_MODE, convertSecretKey, ips);
result = new String(cipher.doFinal(cryptedBytes));
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
private static String hexdump(byte[] ba) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ba.length; i++) {
sb.append(String.format("%02x", ba[i]));
}
return sb.toString();
}
public static void main(String[] args) {
final String key = "ZMiKVoJmzlqFRylAg8IV0hjU";
final String iv = "ZMiKVoJm";
String plain = "http://www.baidu.com";
TripleDES des = new TripleDES(key, iv);
String enc = des.encrypt(plain);
System.out.println(enc);
String plain2 = des.decrypt(enc);
System.out.println(plain2);
}
}
php版本
<?php
// require php7
// php -m | grep openssl
function password_encrypt($input){
if (empty($input)) {
return null;
}
$key = "ZMiKVoJmzlqFRylAg8IV0hjU";
$iv = "ZMiKVoJm";
// php7
$data = openssl_encrypt($input, "DES-EDE3-OFB",
$key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv);
// ---- php5 ----
// $td = mcrypt_module_open(MCRYPT_3DES, '', 'nofb', '');
// mcrypt_generic_init($td, $key, $iv);
// $data = mdecrypt_generic($td, $input);
// mcrypt_generic_deinit($td, $key, $iv);
// mcrypt_module_close($td);
$data = base64_encode($data);
return $data;
}
function password_decrypt($input) {
if (empty($input)) {
return null;
}
$key = "ZMiKVoJmzlqFRylAg8IV0hjU";
$iv = "ZMiKVoJm";
$input = base64_decode($input);
$data = openssl_decrypt($input, "DES-EDE3-OFB",
$key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv);
return $data;
}
$input = "http://www.baidu.com";
$output = password_encrypt($input);
echo $output.PHP_EOL;
echo password_decrypt($output).PHP_EOL;
/*
$ php triple_des.php
30c7lIQeRAFdn2uXhAlbMWp11Lo=
http://www.baidu.com
*/