Golang:将字节数组转换为big.Int

13

我正试图从一个存储在字节数组中的模数和指数创建RSA公钥。经过一些尝试,我得到了以下代码:

func bytes_to_int(b []byte) (acc uint64) {
  length := len(b)
  if length % 4 != 0 {
    extra := (4 - length % 4)
    b = append([]byte(strings.Repeat("\000", extra)), b...)
    length += extra
  }
  var block uint32
  for i := 0; i < length; i += 4 {
    block = binary.BigEndian.Uint32(b[i:i+4])
    acc = (acc << 32) + uint64(block)
  }
return
}

func main() {
  fmt.Println(bytes_to_int(data[:128]))
  fmt.Println(bytes_to_int(data[128:]))
}

这似乎能够工作(尽管我并不确定是否有更好的方法)。我的下一步是将其转换为使用math/big以处理更大的数字。我可以看到Lsh函数来执行<<,但无法弄清楚如何递归地将Uint32(块)添加到big.Int中。

供参考,我试图导入的公钥是存储在密钥环(pubring.mix)中的Mixmaster密钥: http://www.mixmin.net/draft-sassaman-mixmaster-XX.html#key-format http://pinger.mixmin.net/pubring.mix


b = append(make([]byte, extra), b...) 这种写法比使用 strings.Repeat 更高效,祝你在接下来的问题中好运。 - OneOfOne
3个回答

22
你想使用Int.SetBytes方法使用一个[]byte切片创建一个big.int对象。
func (z *Int) SetBytes(buf []byte) *Int

SetBytesbuf解释为大端无符号整数的字节,将z设置为该值,并返回z

根据您提供的文档,您的密钥采用大端格式,因此在应用程序中使用这个函数应该很简单。


谢谢Nick,正是我需要的。值得注意的是,这个大型库还包括一个Uint64函数,用于设置rsa.PublicKey上的指数(E),它是一个整数。 - Steve Crook
如果我想从字节数组中以little-endian格式提取指数和模数,然后使用它们创建公钥,该怎么办呢?你能告诉我如何实现吗? - Vikas Rai

12
import "math/big"

z := new(big.Int)
z.SetBytes(byteSliceHere)

4

就像Nick提到的那样,你可以使用SetBytes,但要注意输入是base64编码的,所以你需要先解码。

示例:

func Base64ToInt(s string) (*big.Int, error) {
    data, err := base64.StdEncoding.DecodeString(s)
    if err != nil {
        return nil, err
    }
    i := new(big.Int)
    i.SetBytes(data)
    return i, nil
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接