1

Ich verwende den Dienstkontoschlüssel, der in GAE generiert wurde, mithilfe der Google IAM-API serviceAccounts.keys.create auf der Clientseite, um Dateien in GCS hochzuladen. Diese API gibt privateKeyData Feld, das ich in dem Client-Seite Code verwenden wie folgt:Wie wird der mit der API serviceAccounts.keys.create generierte Google Cloud Platform-Dienstkontoschlüssel auf der Clientseite in Java verwendet?

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(); 
    } 
} 

Allerdings bekomme ich java.security.InvalidKeyException: invalid key format exception wenn storage.objects().insert genannt wird. Ist dies die korrekte Methode, den Dienstkontoschlüssel zu verwenden, um GoogleCredential zu generieren? P.S: Ich weiß über die JSON- oder P12-Schlüsseldatei. Ich möchte es nicht verwenden, da es nicht zu meinem Anwendungsfall passt.

Antwort

0

Stellt sich heraus, dass das Kennwort für die private Schlüsselzeichenfolge, die serviceAccounts.keys.create generiert wird, notasecret ist. Der folgende Code ruft die PrivateKey aus dem Feld privateKeyData aus der API-Antwort ab. Diese PrivateKey kann verwendet werden, um 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()); 
0

Standardmäßig generiert serviceAccounts.keys.create eine GOOGLE_CREDENTIALS_FILE, ein JSON-Dokument, das den Schlüssel und einige andere Dinge beschreibt. Kunden wie gcloud-java können diese Dateien lesen, etwa so:

StorageOptions options = StorageOptions.builder().projectId(PROJECT_ID) 
    .authCredentials(AuthCredentials.createForJson(
      new FileInputStream(PATH_TO_JSON_KEY))).build(); 
Storage service = options.service(); 

Ihr Code, obwohl, ist eine p12 Schlüsseldatei erwartet. Sie könnten den Schlüssel in der JSON-Datei in ein solches Format extrahieren, aber ein einfacherer Weg wäre wahrscheinlich, serviceAccounts.keys.create mit dem serviceAccountPrivateKey-Parametersatz auf TYPE_PKCS12_FILE aufzurufen.

+0

Vielen Dank. Ich habe den Schlüssel mit 'TYPE_PKCS12_FILE' erzeugt, aber jetzt bekomme ich' java.security.InvalidKeyException: IOException: version nicht übereinstimmend: (unterstützt: 00, parsed: 03' error. –

Verwandte Themen