Go语言跨API调用的分页令牌加解密nonceSize问题
问题解答
首先纠正你的误解:同一密钥下nonce不能固定,GCM模式要求每个加密操作使用唯一的nonce,否则会严重泄露密钥,你的加密逻辑中生成随机nonce的做法是正确的,不能改成固定值。
关于跨调用获取nonceSize的问题,有两种可靠的解决方式:
方式一:直接使用标准GCM的固定nonce长度
Go标准库cipher.NewGCM返回的GCM实例,其NonceSize()固定为12字节(这是NIST推荐的GCM标准nonce长度)。你可以直接在解密代码中硬编码这个值:
func decryptToken(ciphered []byte, keyPhrase string) ([]byte, error) { hashedPhrase := mdHashing(keyPhrase) aesBlock, err := aes.NewCipher([]byte(hashedPhrase)) if err != nil { return nil, err } gcmInstance, err := cipher.NewGCM(aesBlock) if err != nil { return nil, err } // 直接使用固定的12字节作为nonce长度 const nonceSize = 12 if len(ciphered) < nonceSize { return nil, fmt.Errorf("invalid ciphertext") } nonce, cipheredText := ciphered[:nonceSize], ciphered[nonceSize:] originalText, err := gcmInstance.Open(nil, nonce, cipheredText, nil) return originalText, err }
这种方式简单直接,但如果未来改用cipher.NewGCMWithNonceSize自定义nonce长度,需要同步修改硬编码的值。
方式二:解密时重新计算nonceSize
只要密钥短语(keyphrase)相同,解密时生成的AES块和GCM实例就和加密时完全一致,对应的NonceSize()也会相同。你当前的解密代码其实已经在这么做了,跨调用场景下完全可以重新计算这个值,不需要在API间传递:
func decryptToken(ciphered []byte, keyPhrase string) ([]byte, error) { hashedPhrase := mdHashing(keyPhrase) aesBlock, err := aes.NewCipher([]byte(hashedPhrase)) if err != nil { return nil, err } gcmInstance, err := cipher.NewGCM(aesBlock) if err != nil { return nil, err } nonceSize := gcmInstance.NonceSize() if len(ciphered) < nonceSize { return nil, fmt.Errorf("ciphertext too short") } nonce, cipheredText := ciphered[:nonceSize], ciphered[nonceSize:] originalText, err := gcmInstance.Open(nil, nonce, cipheredText, nil) return originalText, err }
这种方式更灵活,即使未来修改GCM的nonce长度,代码也不需要额外调整。
额外建议:完善错误处理
你当前的代码中仅打印错误却继续执行,会导致后续操作在错误状态下运行,容易引发panic或返回无效数据。建议修改函数签名,让加解密函数返回([]byte, error),将错误向上传递给调用方处理。
内容的提问来源于stack exchange,提问作者nimgwfc
相关产品推荐
相关产品推荐

