duanni5726 2015-07-23 16:41
浏览 172
已采纳

从Golang类型提取未导出字段的正确方法是什么?

I'm trying to take an SSH public key (x.crypto.ssh.PublicKey, generated by parsing authorized_keys) and extract a plain old crypto.rsa.PublicKey from it (I know the key is of type ssh-rsa). That means, in ssh-land, the key is of (unexported) type rsaPublicKey.

By using either reflect.Interface() or plain old fmt.Sprintf("%v") I can get a value that looks like:

&{133141753607255377833524803712241410600224583899447743985716492314976605735038858392516407436607315136967439536840885454950028631410155683051419836325912444338003188332463816050354540934271243064035037856360864190161298769948076508355604915775510460445701536855931828420791030023079646791573156484306628882221 35}

I know, by reading the ssh package source, that ssh.rsaPublickey is in fact defined as the type I want:

type rsaPublicKey rsa.PublicKey

and therefore this value is already the thing I want. (In fact, I can, using "%+v", even see that its fields are (of course) named N and E.)

My problem is that I don't know a better way to make Go believe that this is in fact an rsa.PublicKey than to extract each of those numbers into strings with fmt.Sscan, and then convert into big.Int and int, respectively, and then use those two values I just got as the modulus and exponent to create a new rsa.PublicKey.

That works, but seems incredibly nasty. I get that since it's unexported, there's probably no direct route, but surely there's a better way to get the fields than by reconverting their printable representations.

ssh.PublicKey does have a Marshal() function, but that gives me the wire-format representation, and if I go through there, well, I guess it avoids abusing the type system, but I'd just end up writing my own byte-stream-to-big-Int-to-RSA converter there, which doesn't seem like it really helps. At that point I might just as well start with the authorized_keys file and parse it myself, and that seems dumb too.

What's the right way to do this?

  • 写回答

2条回答 默认 最新

  • dongmaonao0505 2015-07-23 17:23
    关注

    You can use reflect to convert that interface value back to the original rsa.PublicKey:

    rsaKey := reflect.ValueOf(sshKey).
        Convert(reflect.TypeOf(&rsa.PublicKey{})).Interface().(*rsa.PublicKey)
    

    Playground with a similar example: http://play.golang.org/p/bcYhYHrIl_.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?