cbasil 最近的时间轴更新
cbasil

cbasil

V2EX 第 311937 号会员,加入于 2018-04-26 15:12:33 +08:00
今日活跃度排名 2059
cbasil 最近回复了
14 小时 13 分钟前
回复了 cbasil 创建的主题 PHP 与银行对接 sm4 国密算法
@ntedshen RSA 也是一个大坑,之前对接的一个项目,接口用到私钥签名、公钥验签加上公钥加密、私钥解密。双方交换公钥。折腾了好久,发现 rsa 加密要分段加密。RSA 密钥长度 1024bit ,加密的时候 117 个字符加密一次,然后把所有的密文拼接成一个密文;解密的时候需要 128 个字符解密一下,然后拼接成数据。具体可以看看这篇文章 https://www.cnblogs.com/meetuj/p/14954533.html
不同语言的加解密处理确实太麻烦了,尤其是对方一句话,我们用的是默认的加密方式。你们自己实现就好了。代码也不给,给一串加密前和加密后的参数。你自己慢慢去试。成功了就是精诚所至金石为开。
15 小时 14 分钟前
回复了 cbasil 创建的主题 PHP 与银行对接 sm4 国密算法
@ca2oh4 我当时也考虑用 golang 写一个脚本,然后 php 通过 http 调用。不过后面解决了就不用了。这是当时写的 golang 案例

```golang
package main

import (
"bytes"
"crypto/cipher"
"encoding/hex"
"fmt"

"github.com/tjfoc/gmsm/sm4"
)

// PKCS5Padding 使用 PKCS5 填充
func PKCS5Padding(src []byte, blockSize int) []byte {
padding := blockSize - len(src)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(src, padtext...)
}

// PKCS5UnPadding 去除 PKCS5 填充
func PKCS5UnPadding(src []byte) []byte {
length := len(src)
unpadding := int(src[length-1])
return src[:(length - unpadding)]
}

// SM4 CBC 模式加密
func sm4CBCEncrypt(key, plaintext, iv []byte) ([]byte, error) {
block, err := sm4.NewCipher(key)
if err != nil {
return nil, err
}

plaintext = PKCS5Padding(plaintext, block.BlockSize())
ciphertext := make([]byte, len(plaintext))
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext, plaintext)
return ciphertext, nil
}

// SM4 CBC 模式解密
func sm4CBCDecrypt(key, ciphertext, iv []byte) ([]byte, error) {
block, err := sm4.NewCipher(key)
if err != nil {
return nil, err
}

plaintext := make([]byte, len(ciphertext))
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(plaintext, ciphertext)
plaintext = PKCS5UnPadding(plaintext)
return plaintext, nil
}

func main() {
key, _ := hex.DecodeString("key") // 16 字节的十六进制密钥
iv, _ := hex.DecodeString("iv") // 16 字节的 IV
plaintext := []byte("This is a secret message.")

// 加密
ciphertext, err := sm4CBCEncrypt(key, plaintext, iv)
if err != nil {
fmt.Println("Encryption error:", err)
return
}
fmt.Printf("Ciphertext (hex): %s\n", hex.EncodeToString(ciphertext))
// 解密
decrypted, err := sm4CBCDecrypt(key, ciphertext, iv)
if err != nil {
fmt.Println("Decryption error:", err)
return
}
fmt.Printf("Decrypted text: %s\n", decrypted)
}
```
17 小时 33 分钟前
回复了 cbasil 创建的主题 PHP 与银行对接 sm4 国密算法
@bagel 银行加密的 IV 就是默认填 0 生成的,你如果用随机数生成 iv ,解密肯定有问题。至于全零 IV 生成,用 str_repeat("\0", 16)更简洁更明确。
之前在深圳城中村租房住。用啥药都不管用,因为蟑螂会从各种地方爬进来。后面改用蟑螂屋,在它必经之路放几个。一晚上就能收获上百只小强。
referer 也可以伪造
121 天前
回复了 wdssmq 创建的主题 Linux lnmp 一键脚本还有靠谱的么?
@SuzutsukiKaede 这教程真的无力吐槽,连 nginx 都要用他私自封装的,php 也是,鬼晓得他里面加了什么鬼后门。
146 天前
回复了 Aura23022 创建的主题 PHP 这段代码是 PHP 混淆吗?
这个 PHP 代码使用了混淆和编码技术,使得代码看起来很复杂。为了理解这个代码的真正意图,我们需要一步一步地解码和解释它。

首先,代码的第一部分定义了一个常量,并通过 explode 函数对一个字符串进行拆分,然后将拆分后的数组元素进行 pack 处理。让我们一步一步还原这些操作。
1. 定义常量和初始化全局数组

php

if(!defined("AA___AA_A")) define("AA___AA_A","AA___AAA_");

$GLOBALS[AA___AA_A] = explode("|L|@|<", "H*|L|@|<41415F5F5F415F5F5F");

这段代码将 AA___AA_A 常量定义为"AA___AAA_",然后将字符串"H*|L|@|<41415F5F5F415F5F5F"按照"|L|@|<"分割成两个部分,存储到$GLOBALS['AA___AAA_']中。分割结果为:

php

$GLOBALS['AA___AAA_'] = array("H*", "41415F5F5F415F5F5F");

2. 定义另一个常量

php

if(!defined(pack($GLOBALS[AA___AA_A][0],$GLOBALS[AA___AA_A][1]))) {
define(pack($GLOBALS[AA___AA_A][0], $GLOBALS[AA___AA_A][1]), ord(62));
}

这里,$GLOBALS['AA___AAA_'][0] 是 "H*", $GLOBALS['AA___AAA_'][1] 是 "41415F5F5F415F5F5F". pack("H*", "41415F5F5F415F5F5F") 将十六进制字符串转换为二进制数据:

php

pack("H*", "41415F5F5F415F5F5F") => "AAA___AAA"

ord(62) 返回 62 。所以这部分代码等价于:

php

if(!defined("AAA___AAA")) define("AAA___AAA", 62);

3. 初始化数组和变量

php

$R31BuEt15 = array(12, 13, 18, 4, 16);
$R31OiRy0 = 5844;
$R31zA8J = array("Ih", "mUN");

这段代码初始化了三个数组和一个变量。
4. 调用 strpos 函数

php

$R31eFbN8I = call_user_func_array("strpos", $R31zA8J);

这相当于:

php

$R31eFbN8I = strpos("Ih", "mUN");

strpos 查找子字符串在字符串中首次出现的位置。显然,"mUN" 在 "Ih" 中不存在,所以 strpos 返回 false 。
5. 检查常量和变量的存在性

php

if($R31eFbN8I) goto R31eWjgx2;
$R318I = !defined("AA___A__A");
if($R318I) goto R31eWjgx2;
if(isset($_J3zIUZr)) goto R31eWjgx2;
goto R31ldMhx2;

这里,由于 $R31eFbN8I 是 false ,所以不会跳转到 R31eWjgx2 ,继续检查 AA___A__A 常量是否定义和 $_J3zIUZr 是否存在。这些都不满足,所以跳转到 R31ldMhx2 。
6. 定义常量和处理字符串

php

R31eWjgx2:
$R31zA8J = array("AA___A__A", "AA___A_A_");
$R31eF8I = call_user_func_array("define", $R31zA8J);
unset($R31zA8J);
goto R31x1;

R31ldMhx2:
R31x1:
$R31zA8J = array(
"|(|O|<",
"H*|(|O|<41415F5F5F5F41415F|(|O|<646566696E65|(|O|<41415F5F5F5F414141|(|O|<746F6B656E|(|O|<|(|O|<756964|(|O|<636F6465|(|O|<6D7367|(|O|<E98080E587BAE799BBE5BD95E68890E58A9FEFBC81|(|O|<E799BBE5BD95E8BF87E69C9FEFBC81|(|O|<E58F82E695B0E99499E8AFAF21"
);

上面是字符串分割操作,具体细节需要进一步处理。

总结:
这个 PHP 代码通过复杂的方式定义了一些常量和变量,然后执行了一些逻辑检查和字符串处理。具体细节需要根据这些字符串的处理方式进一步解码和解释。总体来说,这段代码的核心逻辑是使用混淆技术来隐藏其真正意图。
@zhousir5071 我达达的马蹄是美丽的错误 。 我不是归人,是个过客
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1170 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 14ms · UTC 23:02 · PVG 07:02 · LAX 16:02 · JFK 19:02
Developed with CodeLauncher
♥ Do have faith in what you're doing.