尝试使用Python Google API客户端上载服务帐户的密钥时,公钥无效



我使用Python中的Google API资源管理器来管理服务帐户和推送新密钥。这将是这里记录的方法:https://developers.google.com/resources/api-libraries/documentation/iam/v1/python/latest/iam_v1.projects.serviceAccounts.keys.html#upload

在我按照所需的约定(X509_PEM格式(生成了一个键之后,我调用方法upload((,就像下面的示例一样。

import googleapiclient.discovery
from google.oauth2 import service_account
if __name__ == "__main__":

credentials = service_account.Credentials.from_service_account_file(
filename="path/to/credentials.json",
scopes=["https://www.googleapis.com/auth/cloud-platform"]
)
iam_service = googleapiclient.discovery.build("iam", "v1", credentials=credentials)
public_key = "-----BEGIN CERTIFICATE-----nMIIFDDCCAvQCCQD3eTyPcnYUejANBgkqhkiG9w0BAQUFADBIMUYwRAYDVQQDDD10nYW5ndXktYWJlbC1zYUBhaWdueC10ZXN0LWNsb3VkLXNldHVwLmlhbS5nc2VydmljnZWFjY291bnQuY29tMB4XDTIyMDIwOTE2MzkyMFoXDTIzMDIwOTE2MzkyMFowSDFGnMEQGA1UEAww9dGFuZ3V5LWFiZWwtc2FAYWlnbngtdGVzdC1jbG91ZC1zZXR1cC5pnYW0uZ3NlcnZpY2VhY2NvdW50LmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCnAgoCggIBAJimPN7VYTGikobRD6E29crjdKgB1H3uSh+ViHHGLVjuwMtBVafXeiEBnBAes/IXWUCOosLOG0HKi253+xqZAAleX5g9zFOvUMjhpdJydCVLOxVEs6EfjgikDnU8eiaUJig4sO6VWMFLxELOkMPmKfQN8ASE0ZG/j20tez4/Refo5YqN3Fkt6WNeiOnrQ69KpcGRGPgpo1oT0TViopkeQD+yNBfesXrrPpGYfzQxGKFzkVE5zTRiIBRAAhfnrjfZnLK1rOUPp8ZMfrapZja5xT4sL7Ug2fKVtmULtJK5k9X36bpY6JbwTSPhyi/mncLw49XOpqfoBe03fxQJMes8VH1dwifBRi5wL2Q0s6Kq6s9ZFT3aWAO6WP+l1pVMAnB605edOjgauMsdc/0Fky+IOrwnGTrAyekEfxb7zd1yr9t4d5x/WYQlRnhp9JjuS6nvA5ZGmtn2NaqADWSJ4MuVY7j6Fn9WWQVokRnyb3DgbqhaDuLHN3H6wbgA8U+k0ounmEwOx4VllDkGzFw9xfZdU8jDJu7uM+00s/MHxX30wzdJwnWspBFIpmHhaQQOp2D6nbsggo1Lzn4Xe94ozrhG6mFaoLopL+2SpjBK3LO1L3zMiH65VK3K/CDxZdrBfT5CCnkOJzcBNQxc8a3bQFauZQ9ZAbx1/bFtALXYF/tDNwYh4TUAJuWj01AgMBAAEwDQYJnKoZIhvcNAQEFBQADggIBAHq9SlyKIJwEy5okpXBpKPm7oq+W4Sud7eQNoq+Vg95fnr4R0crHjayj3GaFF5IC1NSq2WRoPqMVZ76uFHRZwnGTOqjIyty4fq8NSe7HJ2jaknRdKBBdnxND+VJrsx8ACGA+GZcNw/s5huekduD22iU3dkDYhERDZUHHcTlakoJxTOndOpLcTzPtTcGOn/cerIpHS2Sdb05qnUicDuOCuD6sz7KufLAEzjKPfve7S7sUtGqn7aqaGjZpR3xf5LkmQCYKwuaFoK3Vz96l3MgHzf2+dxezcDTfUnwU48es04PObasEnoeTlRGvlhkP2QZdlXaXcOZ83sDhgoYcqqaf2EoUm/ycYJ1QjKMw+mlCawx7I4HFin1cDt+xQXOlzI/0eEKhNSM7Vh7wZtzsedga5Pye+i3FqxK/tdoa3jCDmwLdoNps+Wnyrf7JdzSYqHILVSYt3CiUzKsgpyvtK/GDrhHsrIZM2oLQK+4auRSOrfW5x13v9pknlTUlkLEW0F3V5dhiToccYX+d/WG2pKEB/at8MSwTAvj/ZLhD7Q0oqrpAVSP0K4LonhSkTRJov3fyWWfrsEsg7BEWy9iCJYbymy8NupFf6VJxBFdcME9F/pPI18v0hKa8TnmA1ZcJLjPsZE0zmXtDfozlmZIXT2/wP+BKV8p2Rt7dZToMdBLbHc3wL3B9CpoiAMn-----END CERTIFICATE-----"
iam_service.projects().serviceAccounts().keys().upload(
name="projects/my-cloud-project/serviceAccounts/my-sa@my-cloud-project.iam.gserviceaccount.com",
body={
"publicKeyData": public_key
}).execute()

此调用返回以下错误:

<HttpError 400 when requesting https://iam.googleapis.com/v1/projects/aignx-test-cloud-setup/serviceAccounts/tanguy-abel-sa@aignx-test-cloud-setup.iam.gserviceaccount.com/keys:upload?alt=json returned "Invalid value at 'public_key_data' (TYPE_BYTES), Base64 decoding failed for public_key = "-----BEGIN CERTIFICATE-----nMIIFDDCCAvQCCQD3eTyPcnYUejANBgkqhkiG9w0BAQUFADBIMUYwRAYDVQQDDD10nYW5ndXktYWJlbC1zYUBhaWdueC10ZXN0LWNsb3VkLXNldHVwLmlhbS5nc2VydmljnZWFjY291bnQuY29tMB4XDTIyMDIwOTE2MzkyMFoXDTIzMDIwOTE2MzkyMFowSDFGnMEQGA1UEAww9dGFuZ3V5LWFiZWwtc2FAYWlnbngtdGVzdC1jbG91ZC1zZXR1cC5pnYW0uZ3NlcnZpY2VhY2NvdW50LmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCnAgoCggIBAJimPN7VYTGikobRD6E29crjdKgB1H3uSh+ViHHGLVjuwMtBVafXeiEBnBAes/IXWUCOosLOG0HKi253+xqZAAleX5g9zFOvUMjhpdJydCVLOxVEs6EfjgikDnU8eiaUJig4sO6VWMFLxELOkMPmKfQN8ASE0ZG/j20tez4/Refo5YqN3Fkt6WNeiOnrQ69KpcGRGPgpo1oT0TViopkeQD+yNBfesXrrPpGYfzQxGKFzkVE5zTRiIBRAAhfnrjfZnLK1rOUPp8ZMfrapZja5xT4sL7Ug2fKVtmULtJK5k9X36bpY6JbwTSPhyi/mncLw49XOpqfoBe03fxQJMes8VH1dwifBRi5wL2Q0s6Kq6s9ZFT3aWAO6WP+l1pVMAnB605edOjgauMsdc/0Fky+IOrwnGTrAyekEfxb7zd1yr9t4d5x/WYQlRnhp9JjuS6nvA5ZGmtn2NaqADWSJ4MuVY7j6Fn9WWQVokRnyb3DgbqhaDuLHN3H6wbgA8U+k0ounmEwOx4VllDkGzFw9xfZdU8jDJu7uM+00s/MHxX30wzdJwnWspBFIpmHhaQQOp2D6nbsggo1Lzn4Xe94ozrhG6mFaoLopL+2SpjBK3LO1L3zMiH65VK3K/CDxZdrBfT5CCnkOJzcBNQxc8a3bQFauZQ9ZAbx1/bFtALXYF/tDNwYh4TUAJuWj01AgMBAAEwDQYJnKoZIhvcNAQEFBQADggIBAHq9SlyKIJwEy5okpXBpKPm7oq+W4Sud7eQNoq+Vg95fnr4R0crHjayj3GaFF5IC1NSq2WRoPqMVZ76uFHRZwnGTOqjIyty4fq8NSe7HJ2jaknRdKBBdnxND+VJrsx8ACGA+GZcNw/s5huekduD22iU3dkDYhERDZUHHcTlakoJxTOndOpLcTzPtTcGOn/cerIpHS2Sdb05qnUicDuOCuD6sz7KufLAEzjKPfve7S7sUtGqn7aqaGjZpR3xf5LkmQCYKwuaFoK3Vz96l3MgHzf2+dxezcDTfUnwU48es04PObasEnoeTlRGvlhkP2QZdlXaXcOZ83sDhgoYcqqaf2EoUm/ycYJ1QjKMw+mlCawx7I4HFin1cDt+xQXOlzI/0eEKhNSM7Vh7wZtzsedga5Pye+i3FqxK/tdoa3jCDmwLdoNps+Wnyrf7JdzSYqHILVSYt3CiUzKsgpyvtK/GDrhHsrIZM2oLQK+4auRSOrfW5x13v9pknlTUlkLEW0F3V5dhiToccYX+d/WG2pKEB/at8MSwTAvj/ZLhD7Q0oqrpAVSP0K4LonhSkTRJov3fyWWfrsEsg7BEWy9iCJYbymy8NupFf6VJxBFdcME9F/pPI18v0hKa8TnmA1ZcJLjPsZE0zmXtDfozlmZIXT2/wP+BKV8p2Rt7dZToMdBLbHc3wL3B9CpoiAMn-----END CERTIFICATE-----"".

我可以使用gcloud-cli:上传相同的证书

gcloud iam service-accounts keys upload certificate.pem  --iam-account my-cloud-project@my-cloud-project.iam.gserviceaccount.com  --project my-cloud-project --format json

我试图调整我在Python代码的有效负载中发送的密钥的格式,但没有通过;我试着剥去断线,不管有没有包装纸。我在上面链接的文件没有指定有效载荷中的例外格式。此文档描述的格式似乎与我使用的格式相同:https://cloud.google.com/iot/docs/concepts/device-security#public_key_format

你知道我该怎么接电话吗?谢谢

在分析了gcloud命令发送的有效载荷后,我了解到字段publicKeyData必须是base64编码的。当看到错误时,这实际上是有道理的。因此,简单地修复了它:

import base64
...
iam_service.projects().serviceAccounts().keys().upload(
name="projects/my-cloud-project/serviceAccounts/my-sa@my-cloud-project.iam.gserviceaccount.com",
body={
"publicKeyData": base64.b64encode(public_key.encode("utf-8")).decode("utf-8")
}).execute()

请注意,该字符串经过编码、base64编码,然后再次解码,作为字符串而非字节发送。

最新更新