当前位置: 首页 > 知识库问答 >
问题:

无法分析base64 DER编码的ASN。来自Golang iOS的1个公钥

赵华彩
2023-03-14

我在Golang有一个RSA加密的项目,所以现在,我有一个Base64公钥格式,用于加密消息,

我使用了以下代码:

publicKeyBase64 = "MIGJAoGBAJJYXgBem1scLKPEjwKrW8+ci3B/YNN3aY2DJ3lc5e2wNc0SmFikDpow1TdYcKl2wdrXX7sMRsyjTk15IECMezyHzaJGQ9TinnkQixJ+YnlNdLC04TNWOg13plyahIXBforYAjYl2wVIA8Yma2bEQFhmAFkEX1A/Q1dIKy6EfQ+xAgMBAAE="
publicKeyBinary, err := base64.StdEncoding.DecodeString(publicKeyBase64)

publicKeyInterface, err := x509.ParsePKIXPublicKey(publicKeyBinary)
    if err != nil {
    fmt.Println("Could not parse DER encoded public key (encryption key)")
    return "","",err
}

publicKey, isRSAPublicKey := publicKeyInterface.(*rsa.PublicKey)
if !isRSAPublicKey {
    fmt.Println("Public key parsed is not an RSA public key")
    return "","",err
}

encryptedMessage, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, "message")

当我运行此代码时,我得到了这个错误:

Could not parse DER encoded public key (encryption key)

asn1: structure error: tags don't match (16 vs {class:0 tag:2 length:129 isCompound:false}) {optional:false explicit:false application:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false} AlgorithmIdentifier @3

错误指向publicKeyInterface,它无法将Base64解码格式解析为公钥,我的代码有什么问题?

=======更新=====

我的publicKeyBase64是使用二进制数据类型从模型中检索的

当我把它存储在我的mongoDB从我的Rails API,我收到public_keyparams作为Base64格式,但我解码为二进制,然后我用这个代码存储它

def create
  params = device_params      
  public_key = Base64.decode64 device_params[:public_key]
  #device_params[:public_key] value is "MIGJAoGBAJJYXgBem1scLKPEjwKrW8+ci3B/YNN3aY2DJ3lc5e2wNc0SmFikDpow1TdYcKl2wdrXX7sMRsyjTk15IECMezyHzaJGQ9TinnkQixJ+YnlNdLC04TNWOg13plyahIXBforYAjYl2wVIA8Yma2bEQFhmAFkEX1A/Q1dIKy6EfQ+xAgMBAAE="
  params[:public_key] = BSON::Binary.new(public_key, :generic)
  device = Device.find_or_create_by(id: device_params[:id])

  render_success device.update_attributes(params), device
end

当我使用rails代码转换Base64公钥字符串时,它成功了:

rsa_public_key = OpenSSL::PKey::RSA.new(Base64.decode64(public_key))

在我的iOS应用程序中,我使用https://github.com/DigitalLeaves/AsymmetricCrypto要使用此代码生成公钥,请执行以下操作:

AsymmetricCryptoManager.sharedInstance.createSecureKeyPair({ (success, error) -> Void in
   if success {
    print("RSA-1024 keypair successfully generated.")
    let publicKey = AsymmetricCryptoManager.sharedInstance.getPublicKeyData()?.base64EncodedString()

    let url = ENV.BASE_URL + "devices"
    let headers = ["Authentication-Token": CurrentUser.getCurrentUser().token] as! HTTPHeaders
    let params = ["device[user_id]": CurrentUser.getCurrentUser().id!, "device[id]": instanceID,"device[token]": fcmToken, "device[os]": "ios", "device[public_key]": publicKey!]

    Alamofire.request(url, method: .post, parameters: params, encoding: URLEncoding.default, headers: headers)
} else { print("An error happened while generating a keypair: \(error)") }
})

共有1个答案

顾承平
2023-03-14

我们可以扔掉ASN。1.查看其外观的内容:

$ echo "MIGJAoGBAJJYXgBem1scLKPEjwKrW8+ci3B/YNN3aY2DJ3lc5e2wNc0SmFikDpow1TdYcKl2wdrXX7sMRsyjTk15IECMezyHzaJGQ9TinnkQixJ+YnlNdLC04TNWOg13plyahIXBforYAjYl2wVIA8Yma2bEQFhmAFkEX1A/Q1dIKy6EfQ+xAgMBAAE=" | \
    base64 -d | \
    dumpasn1 -
  0 137: SEQUENCE {
  3 129:   INTEGER
       :     00 92 58 5E 00 5E 9B 5B 1C 2C A3 C4 8F 02 AB 5B
       :     CF 9C 8B 70 7F 60 D3 77 69 8D 83 27 79 5C E5 ED
       :     B0 35 CD 12 98 58 A4 0E 9A 30 D5 37 58 70 A9 76
       :     C1 DA D7 5F BB 0C 46 CC A3 4E 4D 79 20 40 8C 7B
       :     3C 87 CD A2 46 43 D4 E2 9E 79 10 8B 12 7E 62 79
       :     4D 74 B0 B4 E1 33 56 3A 0D 77 A6 5C 9A 84 85 C1
       :     7E 8A D8 02 36 25 DB 05 48 03 C6 26 6B 66 C4 40
       :     58 66 00 59 04 5F 50 3F 43 57 48 2B 2E 84 7D 0F
       :     B1
135   3:   INTEGER 65537
       :   }

0 warnings, 0 errors.

格式良好的ASN.1公钥也应该包括算法。我们应该有一行类似于:

  5   9:     OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)

AsymmetricCryptoManager。getPublicKeyData()返回一个非常简单的ASN。1键,没有任何算法信息。这让Go非常不高兴,因为它无法知道这是什么样的钥匙。有关正确导出密钥的详细信息,请参见此处。

如果您可以更改iOS的代码,您应该使用CryptoExport重要性管理器,并使用exportPublicKeyToPEMexportPublicKeyToDER中的一个。这些获取getPublicKeyData的输出并生成其他工具可用的输出。您可以在CryptoExport重要性管理器示例中找到如何使用它们的示例。

如果无法更改密钥导出代码,可以直接在Go中解析。这假设您确信它是RSA公钥:

func main() {
    publicKeyBase64 := "MIGJAoGBAJJYXgBem1scLKPEjwKrW8+ci3B/YNN3aY2DJ3lc5e2wNc0SmFikDpow1TdYcKl2wdrXX7sMRsyjTk15IECMezyHzaJGQ9TinnkQixJ+YnlNdLC04TNWOg13plyahIXBforYAjYl2wVIA8Yma2bEQFhmAFkEX1A/Q1dIKy6EfQ+xAgMBAAE="

    // Base64 decode.
    publicKeyBinary, err := base64.StdEncoding.DecodeString(publicKeyBase64)
    if err != nil {
        panic(err)
    }

    // rsa.PublicKey is a big.Int (N: modulus) and an integer (E: exponent).
    var pubKey rsa.PublicKey
    if rest, err := asn1.Unmarshal(publicKeyBinary, &pubKey); err != nil {
        panic(err)
    } else if len(rest) != 0 {
        panic("rest is not nil")
    }

    fmt.Printf("key: %+v\n", pubKey)
}

这个打印出来:

键:{N:102767083290202280873554060983826675083148443795791447833515664566475334389364583758312108980110921996262487865832851258326049062353432991986398760705560379825908169063986770245967781444794847106351934016144540466696422397564949226710181429429140226472206572796987719088983654589217713611861345869296293449649E: 65537}

现在可以在包rsa函数中使用公钥。

 类似资料:
  • 首先,我需要在C#代码中复制功能。我设法将私钥加载到并调用,但得到的结果与不同。 据我所知,根据这篇文章和这个RFC,当被调用时,没有,openssl不会用digest函数标识符捆绑数据,并跳过ASN.1编码。这意味着对原始数据进行填充和加密。这个工具似乎确认,解密签名看起来像填充的明文数据。 那么用C#怎么做呢?中的所有函数都要求在加密之前指定哈希算法和编码签名。我是否遗漏了什么,或者我将不得不

  • 这是我生成RSA密钥的代码 现在我想转换DER/ASN.1编码字节,也知道使用Java JCE API生成RSA密钥时使用的默认编码格式是什么。

  • 面对公众号推广的多样化,分析公众号用户的来源引流效果对公众号运营人员来说非常重要。「公众号来源分析」,可以直观、清晰的了解各个来源渠道的获客情况、核心节点的转化以及可以准确的甄别来源渠道的优劣,进而可以全面的进行优化,提高转化。 一.功能特点 效果衡量:一键衡量分析公众号来源渠道的拉新获客以及对关键节点的转化。 用户洞察:深入洞察分析各来源渠道带来的用户以及关键行为转化人群的用户特征。 二.应用场

  • 我正在从谷歌地图上提取一些数据,但我似乎不能用它做任何事情。下面是我的代码: 你知道我做错了什么吗?

  • 问题内容: 当我尝试在数据库中插入外来字符时,可能是什么导致此错误? 而我该如何解决呢? 谢谢! 问题答案: 字符U + 201C左双引号在Latin-1(ISO-8859-1)编码中不存在。 这 是 目前在代码页1252(西欧)。这是Windows特定的编码,基于ISO-8859-1,但会将多余的字符放入0x80-0x9F范围内。代码页1252通常与ISO-8859-1混淆,这是一种令人烦恼但现

  • 我的问题和在其他项目中使用.aar文件的问题是一样的。但我想补充更多细节。因此提出了一个新问题。 当我Ctrl+单击该方法时,它会将我带到方法位于C:\users\myuser\.gradle\caches\transforms-1\files-1.1\library.aar\...\old.class中的旧类。我想这就是为什么我得到“无法解决符号”错误的问题。 我怎么解决这个?