如何在ASN.1 Golang中从PrintableString转换为GeneralString?

huangapple go评论89阅读模式
英文:

How to get from PrintableString to GeneralString in ASN.1 Golang?

问题

我有一个 Golang 结构体:

type Dog struct {
    Name string
    UUID *big.Int
}

然后我对其进行了 asn1.Marshal 操作:

dog := Dog{Name: "Rex", UUID: new(big.Int).SetBytes([]byte{0, 0, 7})}
dogAsn, _ := asn1.Marshal(dog)

当我查看 "dogAsn" 的 ASN.1 结构时(使用 dumpasn1 Linux 工具),我看到:

SEQUENCE {
    PrintableString 'Rex'
    INTEGER
        00 00 00 07
}

我希望在那里不是 "PrintableString",而是 "GeneralString":

(期望的输出):

SEQUENCE {
    GeneralString 'Rex'
    INTEGER
        00 00 00 07
}

asn1:"tag:27" 添加到 "Name" 字段中:

type Dog struct {
    Name string `asn1:"tag:27"`
    ...
}

并不能解决我的问题。有什么好的建议吗?提前谢谢!

英文:

I have Golang structure:

type Dog struct {
    Name string
    UUID *big.Int
}

Then I asn1.Marshal it:

dog := Dog{Name: "Rex", UUID: new(big.Int).SetBytes([]byte{0, 0, 7})}
dogAsn, _ := asn1.Marshal(dog)

When I look at the ASN.1 structure of "dogAsn" (using dumpasn1 Linux utility)I see:

SEQUENCE {
    PrintableString 'Rex'
    INTEGER
        00 00 00 07
    }

I wish NOT to have "PrintableString" there, but instead "GeneralString":

(Desired output):

SEQUENCE {
    GeneralString 'Rex'
    INTEGER
        00 00 00 07
}

Adding asn1:"tag:27" to the "Name" field:

type Dog struct {
    Name string `asn1:"tag:27"`
    ...
}

Doesn't solve my issue. Any good ideas? Thanks in advance!

答案1

得分: 1

> 找到解决方案!

==============================

如果你需要在Golang中创建一个ASN.1 GeneralString,可以按照以下步骤进行操作:

type Dog struct {
    Name asn1.RawValue // 之前是 "string"
    UUID *big.Int
}
dogGeneralStr := asn1.RawValue{Tag: asn1.TagGeneralString, Bytes: []byte("Rex")}
dog := Dog{Name: dogGeneralStr, UUID: new(big.Int).SetBytes([]byte{0, 0,7})}
dogAsn, _ := asn1.Marshal(dog)
 SEQUENCE {
        GeneralString 'Rex'
        INTEGER
        00 00 00 07
    }

P.S 在你的程序中,每当你需要将dog.Name转换为[]byte或string形式时,只需使用dogGeneralStr.Bytes或string(dogGeneralStr.Bytes)即可。

英文:

> Solution has been found!

==============================

If you need to create an ASN.1 GeneralString in a Golang, then do this:

1.

type Dog struct {
    Name asn1.RawValue // previously was "string"
    UUID *big.Int
}

2.

dogGeneralStr := asn1.RawValue{Tag: asn1.TagGeneralString, Bytes: []byte("Rex")}
dog := Dog{Name: dogGeneralStr, UUID: new(big.Int).SetBytes([]byte{0, 0,7})}
dogAsn, _ := asn1.Marshal(dog)
 SEQUENCE {
        GeneralString 'Rex'
        INTEGER
        00 00 00 07
    }

P.S Then inside your program, whenever you need this dog.Name in a []byte or string form you just do: dogGeneralStr.Bytes or string(dogGeneralStr.Bytes) respectively.

答案2

得分: 0

你无法使用内置库完成这个操作。marshalling logic 允许你在 IA5StringPrintableStringNumericStringUTF8String 之间进行选择。

我找到了一个替代的 ASN.1 库:https://github.com/Logicalis/asn1
但是它已经不再维护,并且将所有的字符串都编码为 OctetString

所以你最好的选择是复制 encoding/asn1 的源代码,并在编码时添加一个自定义标签来指示 GeneralString。也许你甚至可以将其作为一个 PR 提交。

英文:

You can't do this with the built in library. The marshalling logic allows you to pick between IA5String, PrintableString, NumericString or UTF8String.

I found an alternative ASN.1 library: https://github.com/Logicalis/asn1
But is is no longer maintained and also encodes all strings as OctetString

So you best bet is to copy the source code of encoding/asn1 and add a custom tag to indicate GeneralString while encoding. Perhaps you could even make a PR out of it.

huangapple
  • 本文由 发表于 2022年4月25日 16:22:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/71996505.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定