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 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?
  • ¥15 乘性高斯噪声在深度学习网络中的应用
  • ¥15 运筹学排序问题中的在线排序
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛