目录

易语言支持库中的加密数据与解密数据

目录

易语言数据操作支持库一中存在这样一对算法函数

调用格式: 〈字节集〉 加密数据 (字节集 字节集数据,文本型 密码文本,[整数型 加密算法]) - 数据操作支持库一->数据加解密
英文名称:Encrypt
加密一段字节集数据,返回加密后的结果字节集。如果失败,返回空字节集。本命令为初级命令。
	参数<1>的名称为“字节集数据”,类型为“字节集(bin)”。为命令提供所需的字节集数据。
	参数<2>的名称为“密码文本”,类型为“文本型(text)”。
	参数<3>的名称为“加密算法”,类型为“整数型(int)”,可以被省略。指定具体使用的加密算法,可以为以下常量值之一:1: #DES算法; 2: #RC4算法。加密和解密必须使用相同的算法,有关算法的具体说明请参阅有关文献。如果本参数被省略,则默认值为1,即DES算法。
调用格式: 〈字节集〉 解密数据 (字节集 字节集数据,文本型 密码文本,[整数型 加密算法]) - 数据操作支持库一->数据加解密
英文名称:Decrypt
解密一段加密后的字节集数据,返回解密后的结果字节集。注意本命令并不对密码文本进行校验,如果密码提供错误,将返回错误的结果。如果失败,返回空字节集。本命令为初级命令。
	参数<1>的名称为“字节集数据”,类型为“字节集(bin)”。为命令提供所需的字节集数据。
    参数<2>的名称为“密码文本”,类型为“文本型(text)”。
    参数<3>的名称为“加密算法”,类型为“整数型(int)”,可以被省略。指定具体使用的加密算法,可以为以下常量值之一:1: #DES算法; 2: #RC4算法。加密和解密必须使用相同的算法,有关算法的具体说明请参阅有关文献。如果本参数被省略,则默认值为1,即DES算法。

这个函数里面的DES算法是不标准的,如果我们需要逆向算法或者移植语言,就会陷入坑中。。。。

根据别人研究的资料, 得知将密钥进行变换就可以对齐结果,实现Go语言代码如下:

package Utils

import (
	"bytes"
	"crypto/des"
	"encoding/binary"
	"math/bits"
)

func zeroPadding(ciphertext []byte, blockSize int) []byte {
	padding := blockSize - len(ciphertext) % blockSize
	padtext := bytes.Repeat([]byte{0}, padding)
	return append(ciphertext, padtext...)
}

func E_加密数据_DES(加密数据 []byte,密码文本 string)([]byte,error)  {

	key := make([]byte,8)

	//压缩密钥
	sIndex := 0
	for _,eKey := range 密码文本{
		key[sIndex] = byte(eKey) ^ key[sIndex]
		sIndex = sIndex + 1
		if sIndex == 8{
			sIndex = 0
		}
	}

	//转换密钥
	for n,_ := range key{
		key[n] = bits.Reverse8(key[n])
	}

	block,err := des.NewCipher(key)
	if err!=nil{
		return nil,err
	}

	//需要在数据前面追加长度
	inputData := make([]byte,4)
	binary.LittleEndian.PutUint32(inputData,uint32(len(加密数据)))
	inputData = append(inputData, 加密数据...)
	inputData = zeroPadding(inputData,block.BlockSize())

	//开始执行加密
	encryptedData := make([]byte, len(inputData))
	data := inputData
	dst := encryptedData
	bs := block.BlockSize()
	for len(data) > 0 {
		// Mandarin encryption is made according to blocksize
		// Can use the Go key to encrypt
		block.Encrypt(dst, data[:bs])
		data = data[bs:]
		dst = dst[bs:]
	}
	return encryptedData, nil
}

func E_解密数据_DES(解密数据 []byte,密码文本 string)([]byte,error)  {

	key := make([]byte,8)

	//压缩密钥
	sIndex := 0
	for _,eKey := range 密码文本{
		key[sIndex] = byte(eKey) ^ key[sIndex]
		sIndex = sIndex + 1
		if sIndex == 8{
			sIndex = 0
		}
	}

	//转换密钥
	for n,_ := range key{
		key[n] = bits.Reverse8(key[n])
	}

	block,err := des.NewCipher(key)
	if err!=nil{
		return nil,err
	}

	//开始执行解密
	decryptedData := make([]byte, len(解密数据))
	data := 解密数据
	dst := decryptedData
	bs := block.BlockSize()
	for len(data) > 0 {
		// Mandarin encryption is made according to blocksize
		// Can use the Go key to encrypt
		block.Decrypt(dst, data[:bs])
		data = data[bs:]
		dst = dst[bs:]
	}

	//读取头部数据
	recvLen := binary.LittleEndian.Uint32(decryptedData)
	return decryptedData[4:recvLen+4], nil
}

另外附上一份别人写的python版本

from Crypto.Cipher import DES
import struct

def reverse_bytes(b):
    assert type(b) == bytes
    ba = bytearray(b)
    for i in range(0, len(b)):
        ba[i] = int(format(b[i], '0>8b')[::-1], 2)
    return bytes(ba)


def get_new_key(key):
    ba = bytearray(8)
    i = 0
    for b in key:
        ba[i] = b ^ ba[i]
        i = i + 1 if i < 8 else 0
    return bytes(ba)


# zero padding
def padding(d):
    ba = bytearray(d)
    while len(ba) % 8 != 0:
        ba.append(0)

    return bytes(ba)


def append_len(d):
    assert type(d) == bytes
    length = struct.pack('<L', len(d))

    return bytes(length + d)


def remove_len(d):
    assert type(d) == bytes
    return d[4:]


def e_des_encrypt(plain, key):
    des = DES.new(reverse_bytes(get_new_key(key)), DES.MODE_ECB)
    return des.encrypt(padding(append_len(plain)))


def e_des_decrypt(raw, key):
    des = DES.new(reverse_bytes(get_new_key(key)), DES.MODE_ECB)
    t = des.decrypt(raw)
    return remove_len(t)

# 易语言:
  # 输出调试文本(字节集_字节集到十六进制 (加密数据 (到字节集 (“123456789”), “123456789”, #DES算法)))
  # 输出:
  # 53DEE70DD231541839EB99553B8B056D
  # --------------------------------
  # python:
  plain = b'123456789'
  key = b'123456789'
  ciph = e_des_encrypt(plain, key)

  print(ciph.hex().upper())
  print(e_des_decrypt(ciph, key).decode())
  # 输出:
  # 53DEE70DD231541839EB99553B8B056D123456789
  # 123456789

参考资料

https://monvvv.github.io/2019/10/09/A-weird-way-of-DES-implementation-of-Elang.html