[英]Convert RSA Public key (2048 bit) from XML format to DER ASN.1 public key for iOS
[英]Could not parse base64 DER-encoded ASN.1 public key from iOS in Golang
我在 Golang 中有一個帶有 RSA enryption 的項目,所以現在,我有一個 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 是從二進制數據類型的模型中檢索的
當我從 Rails API 將它存儲在我的 mongoDB 中時,我以 Base64 格式接收 public_key 參數,但我將它解碼為二進制文件,然后我用此代碼存儲它
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)") }
})
我們可以轉儲 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 代碼,則應改為使用CryptoExportImportManager並使用exportPublicKeyToPEM
或exportPublicKeyToDER
。 這些獲取getPublicKeyData
的輸出並生成其他工具可用的輸出。 您可以在CryptoExportImportManager 示例中找到有關如何使用它們的示例。
如果您無法更改密鑰導出代碼,則可以直接在 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:+102767083290202280873554060983826675083148443795791447833515664566475334389364583758312108980110921996262487865832851258326049062353432991986398760705560379825908169063986770245967781444794847106351934016144540466696422397564949226710181429429140226472206572796987719088983654589217713611861345869296293449649 E:65537}
您現在可以在包 rsa 函數中使用您的公鑰。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.