GO-使用golang解密使用php的openssl

tech2024-08-23  149

GO-使用golang解密使用php的openssl_encrypt加密的结果,以及关于和java通信时的一些说明

直接看源码

<?php $key = "1234567887654321"; var_dump(bin2hex(openssl_encrypt('1234','AES-128-ECB',$key,OPENSSL_RAW_DATA )));

结果

4f87a3233278f5f9539ffd3b36b5ee37

go源码

func main() { key := []byte("1234567887654321") c,_ := aes.NewCipher(key) orData , _:= hex.DecodeString("4f87a3233278f5f9539ffd3b36b5ee37") ldata := len(orData) decrypted := make([]byte, ldata) c.Decrypt(decrypted, orData) fmt.Println(string(PKCS5UnPadding(NullUnPadding(decrypted)))) } func NullUnPadding(in []byte) []byte { return bytes.TrimRight(in, string([]byte{0})) } func PKCS5UnPadding(src []byte) []byte { length := len(src) unpadding := int(src[length-1]) if length - unpadding < 0 { return []byte("") } return src[:(length - unpadding)] }

结果

1234 Process finished with exit code 0

其中NullUnPadding 和 PKCS5UnPadding两种编码的填充方式. 对于原值大于16为的情况上边的方法就不行了,原因是go在源码种处理的时候要求最大的字节序为16个一组这个时候是处理不到16位以后的编码的,严格的说上边的方法其实是错的. 真正的处理方法如下

<?php $key = "1234567887654321"; var_dump(bin2hex(openssl_encrypt('12341111111111111111111111111111111111111111111111111111111111111111111111111','AES-128-ECB',$key,OPENSSL_RAW_DATA )));

结果

b1d59e6db526dd97e71b397ea14972a33c69425fed4825dcd14e42574cf1349d3c69425fed4825dcd14e42574cf1349d3c69425fed4825dcd14e42574cf1349dfbb37435d77959a9bf5e363d7d491728

go源码

func main() { key := []byte("1234567887654321") c,_ := aes.NewCipher(key) orData , _:= hex.DecodeString("b1d59e6db526dd97e71b397ea14972a33c69425fed4825dcd14e42574cf1349d3c69425fed4825dcd14e42574cf1349d3c69425fed4825dcd14e42574cf1349dfbb37435d77959a9bf5e363d7d491728") ldata := len(orData) decrypted := make([]byte, ldata) //c.Decrypt(decrypted, orData) //关键在这里--start start := 0 end := 16 step := 16 for ; start+1 <= ldata ; { c.Decrypt(decrypted[start:end], orData[start:end]) start += step end += step } //关键在这里--end fmt.Println(string(PKCS5UnPadding(NullUnPadding(decrypted)))) } func NullUnPadding(in []byte) []byte { return bytes.TrimRight(in, string([]byte{0})) } func PKCS5UnPadding(src []byte) []byte { length := len(src) unpadding := int(src[length-1]) if length - unpadding < 0 { return []byte("") } return src[:(length - unpadding)] }

执行结果

12341111111111111111111111111111111111111111111111111111111111111111111111111 Process finished with exit code 0

上边就是完整的通讯方式. 但是,凡事都有个但是. java在错AES-128-ECB加密的时候也不知道是不是一个老师教的或者是都百度的同一篇文章,通常都会对原始的key做一次处理,java的代码不方便贴出来,大家可以百度或者找找其他地方的代码.这里只给出php和go针对java这种方式的处理方式 php针对java的解密

$key = "123456788765432111111111111111111111111"; $key = substr(openssl_digest(openssl_digest($key, 'sha1', true), 'sha1', true), 0, 16); var_dump(openssl_decrypt(hex2bin("cf6315397e6f46e8fdeaf770693e982724197d75a083b1aff5118807eb1de45a24197d75a083b1aff5118807eb1de45a24197d75a083b1aff5118807eb1de45a8fd74b80c43b8f9af93b0bbd38b0bffd"), 'aes-128-ecb', $key, OPENSSL_RAW_DATA));

go代码

func main() { t:=sha1.New() data := "1234567887654321" io.WriteString(t,data) bs := t.Sum(nil) t.Reset() io.WriteString(t,string(bs)) key := t.Sum(nil) //key := []byte("1234567887654321") c,_ := aes.NewCipher(key[0:16]) orData , _:= hex.DecodeString("cf6315397e6f46e8fdeaf770693e982724197d75a083b1aff5118807eb1de45a24197d75a083b1aff5118807eb1de45a24197d75a083b1aff5118807eb1de45a8fd74b80c43b8f9af93b0bbd38b0bffd") ldata := len(orData) decrypted := make([]byte, ldata) //c.Decrypt(decrypted, orData) start := 0 end := 16 step := 16 for ; start+1 <= ldata ; { c.Decrypt(decrypted[start:end], orData[start:end]) start += step end += step } fmt.Println(string(PKCS5UnPadding(NullUnPadding(decrypted)))) } func NullUnPadding(in []byte) []byte { return bytes.TrimRight(in, string([]byte{0})) } func PKCS5UnPadding(src []byte) []byte { length := len(src) unpadding := int(src[length-1]) if length - unpadding < 0 { return []byte("") } return src[:(length - unpadding)] }

然后其他的方式基本就简单了这里就不做过多介绍了,key的长度处理可以看上一篇AES-128-CBC种的介绍

最新回复(0)