如何在Java客户端使用serviceAccounts.keys.create API生成的Google云平台服务帐户密钥?
我正在使用GAE中生成的服务帐户密钥,使用客户端的如何在Java客户端使用serviceAccounts.keys.create API生成的Google云平台服务帐户密钥?,java,google-app-engine,google-cloud-storage,google-api-java-client,service-accounts,Java,Google App Engine,Google Cloud Storage,Google Api Java Client,Service Accounts,我正在使用GAE中生成的服务帐户密钥,使用客户端的servicecomports.keys.createGoogle IAM API将文件上载到GCS。此API返回我在客户端代码中使用的privateKeyData字段,如下所示: public class GCSTest { public static final String CLOUD_STORAGE_SCOPE = "https://www.googleapis.com/auth/cloud-platfor
servicecomports.keys.create
Google IAM API将文件上载到GCS。此API返回我在客户端代码中使用的privateKeyData
字段,如下所示:
public class GCSTest {
public static final String CLOUD_STORAGE_SCOPE =
"https://www.googleapis.com/auth/cloud-platform";
private GoogleCredential credential = null;
private HttpTransport HTTP_TRANSPORT = null;
private Storage storage = null;
private final JsonFactory json_factory = JacksonFactory
.getDefaultInstance();
public String APPLICATION_NAME = "GCSTest";
private String privKeyString =
<copy the privateKeyData from response of serviceAccounts.keys.create>;
public void startTests() {
initStorageService();
writeObject();
}
private void initStorageService() {
List<String> scopeList = new ArrayList<String>();
scopeList.add(CLOUD_STORAGE_SCOPE);
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
byte[] privKeyBytes = Base64.decodeBase64(privKeyString.getBytes());
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privKeyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = kf.generatePrivate(spec);
credential =
new GoogleCredential.Builder()
.setTransport(HTTP_TRANSPORT)
.setJsonFactory(json_factory)
.setServiceAccountId(
"<service_account_name>@<project-id>.iam.gserviceaccount.com")
.setServiceAccountScopes(scopeList)
.setServiceAccountPrivateKey(privateKey)
.setServiceAccountPrivateKeyId(
"<key_id>")
.build();
storage =
new Storage.Builder(HTTP_TRANSPORT, json_factory,
credential).setApplicationName(APPLICATION_NAME)
.build();
}
private void writeObject() {
String fileName = "StorageSample";
Path tempPath = Files.createTempFile(fileName, ".txt");;
Files.write(tempPath, "Sample file".getBytes());
File tempFile = tempPath.toFile();
tempFile.deleteOnExit();
InputStreamContent contentStream =
new InputStreamContent("text/plain", new FileInputStream(
tempFile));
contentStream.setLength(tempFile.length());
StorageObject objectMetadata = new StorageObject().setName(fileName);
Storage.Objects.Insert insert =
storage.objects().insert(<bucket_name>,
objectMetadata, contentStream);;
insert.setName(fileName);
insert.execute();
}
}
公共类GCSTest{
公共静态最终字符串云存储范围=
"https://www.googleapis.com/auth/cloud-platform";
私有Google凭证凭证=null;
私有HttpTransport HTTP_TRANSPORT=null;
私有存储=null;
私有最终JsonFactory json_factory=JacksonFactory
.getDefaultInstance();
公共字符串应用程序\u NAME=“GCSTest”;
私有字符串privKeyString=
;
公共无效开始测试(){
initStorageService();
writeObject();
}
私有存储服务(){
List scopeList=new ArrayList();
scopeList.add(云存储范围);
HTTP_TRANSPORT=GoogleNetHttpTransport.newTrustedTransport();
byte[]privKeyBytes=Base64.decodeBase64(privKeyString.getBytes());
PKCS8EncodedKeySpec spec=新的PKCS8EncodedKeySpec(privKeyBytes);
KeyFactory kf=KeyFactory.getInstance(“RSA”);
PrivateKey PrivateKey=kf.generatePrivate(规范);
凭证=
新建GoogleCredential.Builder()
.setTransport(HTTP_传输)
.setJsonFactory(json_工厂)
.SetServiceAccounted(
“@.iam.gserviceaccount.com”)
.setServiceAccountScopes(范围列表)
.setServiceAccountPrivateKey(privateKey)
.setServiceAccountPrivateKeyId(
"")
.build();
储藏=
new Storage.Builder(HTTP_传输、json_工厂、,
凭证).setApplicationName(应用程序名称)
.build();
}
私有void writeObject(){
字符串fileName=“StorageSample”;
Path tempPath=Files.createTempFile(文件名“.txt”);;
write(tempPath,“Sample file”.getBytes());
File tempFile=tempPath.toFile();
tempFile.deleteOnExit();
InputStreamContent内容流=
新的InputStreamContent(“文本/普通”,新文件InputStream(
临时文件);
setLength(tempFile.length());
StorageObject objectMetadata=新的StorageObject().setName(文件名);
Storage.Objects.Insert=
storage.objects().insert(,
对象元数据(contentStream);;
插入.setName(文件名);
insert.execute();
}
}
但是,当调用storage.objects().insert
时,我得到java.security.InvalidKeyException:invalid key format exception
。
这是使用服务帐户密钥生成GoogleCredential
的正确方法吗?
我知道JSON或P12密钥文件。我不想使用它,因为它不适合我的用例。默认情况下,
servicecomports.keys.create
生成一个GOOGLE\u凭证文件,它是一个描述密钥和其他内容的JSON文档。像这样的客户端可以读取这些文件,如下所示:
StorageOptions options = StorageOptions.builder().projectId(PROJECT_ID)
.authCredentials(AuthCredentials.createForJson(
new FileInputStream(PATH_TO_JSON_KEY))).build();
Storage service = options.service();
但是,您的代码需要一个p12密钥文件。您可以将JSON文件中的密钥提取为这样的格式,但更简单的方法可能是调用
servicecomports.keys.create
,将servicecomportprivatekey
参数设置为TYPE\u PKCS12\u FILE
结果是使用servicecomports.keys.create
生成的私钥字符串的密码是notacret
。以下代码从API响应的privateKeyData
字段中获取PrivateKey
。此PrivateKey
可用于获取GoogleCredential
byte[] privKeyBytes = Base64.decodeBase64(privKeyString.getBytes());
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new ByteArrayInputStream(privKeyBytes), "notasecret".toCharArray());
PrivateKey privateKey = (PrivateKey) ks.getKey("privatekey", "notasecret".toCharArray());
非常感谢。我使用
TYPE\u PKCS12\u文件
生成了密钥,但现在我得到了java.security.InvalidKeyException:IOException:version mismatch:(支持:00,解析:03
错误)。