1
momo7411 21 天前 via Android
iv 固定?
|
2
bagel 21 天前 5
IV 写死不用看了,屎山加屎而已,至于对不对,根本无人在意。
|
3
joyhub2140 21 天前
iv 写死,哈哈,那每次加密的密文是不是都一样?
|
4
hervey0424 21 天前
直接用他们的开发语言弄个中间层比研究这玩意强多了
|
5
cbasil OP @bagel 银行加密的 IV 就是默认填 0 生成的,你如果用随机数生成 iv ,解密肯定有问题。至于全零 IV 生成,用 str_repeat("\0", 16)更简洁更明确。
|
9
majula 21 天前
@momo7411 @bagel @joyhub2140
固定 iv 是可行的,只要你确保第一个 block 的明文不重复(比如用一个自增 id ),且确保其无法被攻击者自由选择即可。这时,第一个 block 的密文等效于一个用 CSPRNG 生成的 iv NIST SP 800-38A 官方支持了这种用法(见 Appendix C ) 有的时候甚至不得不这样做,尤其是在没有可靠的 random source 可用的时候(比如一些嵌入式场景) |
10
ca2oh4 21 天前
php 对接属实有点困难,国密那一套一开始好像是国内的区块链研究机构搞的.记得 有发布官方的 sdk 来着(golang 版本)
|
11
YUCOAT 21 天前
我以前搞国密的时候,用到了 GmSSL ,你可以参考一下
|
12
dode 21 天前
用 Java 包做,bouncycastle
|
13
ntedshen 21 天前
话说我这里有个阿里的 javasdk 用的个 RSA/ECB/OAEPPadding ,似乎完全找不到其他语言的方案。。。
找 ai 要了几个 nodejs 的包但是实际上加密加不出来。。。 现在专门跑了个 tomcat 当接口用着的。。。 |
14
cbasil OP @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) } ``` |
15
AoEiuV020JP 21 天前
这块都一样,国密和国际算法都是这些坑,
我公司几年前做接口加固时我写文档教其他各端实现就踩了这种坑, 家家有本难念的经,尤其 js 连“字节数组”的概念都没有,整数类型也没有字节数的概念,我都很难给他们解释, 最终文档里是单开一页用来举例子,就是涉及到的每种加密算法封装后的输入输出给个具体例子参考,涉及字节数组就强调该字节数组 base64 编码或者 16 进制编码后是某某某, 但后面其他同事设计别的加密时还是会做出比如 长度 16 的字节数组,先 base64 编码成长度 24 的字符串再截取 16 字符转成 新的 16 字节作为密钥使用,这种意义不明麻烦还降低安全性的操作,但一开始定好了这一套操作后面别人实现就都得做成一样的, |
16
GiggleSmile 21 天前
@AoEiuV020JP 说得很对。
|
17
cbasil OP @ntedshen RSA 也是一个大坑,之前对接的一个项目,接口用到私钥签名、公钥验签加上公钥加密、私钥解密。双方交换公钥。折腾了好久,发现 rsa 加密要分段加密。RSA 密钥长度 1024bit ,加密的时候 117 个字符加密一次,然后把所有的密文拼接成一个密文;解密的时候需要 128 个字符解密一下,然后拼接成数据。具体可以看看这篇文章 https://www.cnblogs.com/meetuj/p/14954533.html
不同语言的加解密处理确实太麻烦了,尤其是对方一句话,我们用的是默认的加密方式。你们自己实现就好了。代码也不给,给一串加密前和加密后的参数。你自己慢慢去试。成功了就是精诚所至金石为开。 |
18
brando 21 天前
这种我一律要 SDK 的,没这标准咋搞,靠理解还是猜来猜去?
|
20
fengpan567 20 天前
想起来之前电网做安全测试,有个国密算法功能测试不通过,他们说我们解密出来的都是错误明文,还不给我们看正确的解密明文。最后搞了一周才搞清楚,那群傻屌只解密到 16 进制,没有完全解密到明文
|