中广协 CAID 公钥加密 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
GopherDaily
V2EX    程序员

中广协 CAID 公钥加密

  •  1
     
  •   GopherDaily 271 天前 2384 次点击
    这是一个创建于 271 天前的主题,其中的信息可能已经有所发展或是发生改变。

    今天接了个内部外包需求,要接中广协的 CAID 。

    看了半天没看懂文档里对返回内容用“公钥解密”是什么意思,网络上也没搜到太多信息, 所以把处理方式共享下。

    文档里面的例子是 JAVA ,我实现的逻辑是 Go ,关键信息来自 https://stackoverflow.com/questions/68984685/go-rsa-decrypt-using-public-key-implementation-from-java

    package caid import ( "bytes" "crypto/rsa" "encoding/base64" "errors" "fmt" "io" "log" "math/big" ) func decrypt(data string) ([]byte, error) { raw, err := base64.StdEncoding.DecodeString(data) if err != nil { return nil, fmt.Errorf("base64 decode %w: %s", err, data) } reader := bytes.NewReader(raw) var writer bytes.Buffer chunk := make([]byte, maxDecryptBlock) for { n, err := io.ReadFull(reader, chunk) if err != nil && errors.Is(err, io.ErrUnexpectedEOF) { return nil, fmt.Errorf("read decrypted data: %w", err) } if n == 0 { break } decryptChunk(chunk, &writer, pubKey) } output := bytes.TrimRight(bytes.TrimLeft(writer.Bytes(), "\x00"), "\n") if bytes.Count(output, []byte("\x00")) > 0 { after := bytes.ReplaceAll(output, []byte("\x00"), []byte{}) log.Println("WARN: remove \x00 from caid's response", "before", output, "after", after) output = after } return output, nil } func decryptChunk(chunk []byte, writer *bytes.Buffer, pubKey *rsa.PublicKey) { // Decrypt each signature chunk ciphertextInt := new(big.Int) ciphertextInt.SetBytes(chunk) decryptedPaddedInt := doDecrypt(new(big.Int), pubKey, ciphertextInt) // Remove padding decryptedPaddedBytes := make([]byte, pubKey.Size()) decryptedPaddedInt.FillBytes(decryptedPaddedBytes) start := bytes.Index(decryptedPaddedBytes[1:], []byte{0}) + 1 // // 0001FF...FF00<data>: Find index after 2nd 0x00 decryptedBytes := decryptedPaddedBytes[start:] // Write decrypted signature chunk writer.Write(decryptedBytes) } func doDecrypt(c *big.Int, pub *rsa.PublicKey, m *big.Int) *big.Int { // Textbook RSA e := big.NewInt(int64(pub.E)) c.Exp(m, e, pub.N) return c } 
    第 1 条附言    271 天前
    公钥解密
    第 2 条附言    271 天前
    本来只是用来给相关人员搜索的,所以没说明。


    1. 中广协的文档自己定义的是用公钥解密他们返回的内容。
    2. 但像我这样的半吊子选手应该了解,私钥签名,公钥验签,或者公钥加密,私钥解密,不存在私钥加密,公钥解密这一套
    3. 人家给的 Java 的代码例子确实是解密,虽然跑不起来,但应该能跑
    4. 这就涉及到一个 Java Cipher 的隐藏逻辑,如果你用私钥&RSA 去加密数据,基本等于签名
    5. 如果你没搜索到上面的逻辑,我估计要花很久才能走通他们的逻辑
    9 条回复    2025-01-17 12:08:06 +08:00
    pandaex
        1
    pandaex  
       271 天前 via Android
    如果是想问为啥是公钥解密,硬想一个可以是用于认证这个数据是官方给出的
    duzhuo
        2
    duzhuo  
       271 天前
    @pandaex 那不是签名吗
    ma46
        3
    ma46  
       271 天前
    就字面意思啊, 用公钥来解密对方发来的数据, 如果你不知道公钥是什么就找对方要
    sagaxu
        4
    sagaxu  
       271 天前   1
    公钥加密,私钥解密。私钥签名,公钥验签。签名是确保发送人不被伪造,加密是为了防止被中间人攻击嗅探数据。

    在强安全场景,加密和签名经常一起用。我们也经常看到用非对称加密打包对称加密的密码,提高安全性的同时,减小计算压力,如 SSL 。

    如果同时写 Java 和 Go ,一定会遇到 PKCS1 和 PKCS8 格式差异。
    yankebupt
        5
    yankebupt  
       271 天前
    虽然公钥是公开的所以私钥处理后并不会赋予秘密属性,但你就说是不是解密算法吧……( doge
    ZRS
        6
    ZRS  
       271 天前
    可以,但比较脱裤子放屁,就当是混淆传输吧
    jocover
        7
    jocover  
       271 天前
    就是把 d 和 e 换下就行了

    // mpz_powm(ct, pt, e, n);//公钥加密
    mpz_powm(ct, pt, d, n);//私钥加密
    gmp_printf("Encoded: %Zx\n", ct);

    // mpz_powm(pt, ct, d, n); //私钥解密
    mpz_powm(pt, ct, e, n); //公钥解密
    gmp_printf("Decoded: %Zx\n", pt);
    murmur
        8
    murmur  
       271 天前
    @ZRS 这是商密还是等保 3 的要求,我也既不清楚了,要求 api 接口不能露路径,body 和 request 都是加密传输

    就是类似所有的接口都是/api/entry ,如果碰到什么/user/info 就算你没加密全
    marvin001
        9
    marvin001  
       269 天前
    我测试好像还是不行
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5203 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 03:55 PVG 11:55 LAX 20:55 JFK 23:55
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86