2013-02-26 2 views
2

App Engine에서 Google Cloud Storage로 작업 중이며 POST 양식을 사용하여 GCS에 파일을 업로드하려고합니다. 내가 가지고있는 문제는 정책 문서에 서명하는 데 필요한 단계입니다. API 콘솔이 준 client_secrets.json에서 문자열 인 client_secret을 쉽게 가져올 수 있습니다. 그러나 서명을 만들려면 해당 문자열을 PrivateKey 개체로 변환해야합니다. 여기처럼 내 코드를 보이는 내용은 다음과 같습니다으로는 위에서 언급 한clientsecret을 개인 키로 변환

//create the policy document and encode it 
String policyDocument = ... //omitted for brevity 
String encodedPolicy = Base64.encodeString(policyDocument); 

//sign using SHA256 with RSA 
String secretKey = ... //I fetch this from client_secrets.json 
Signature sig = Signature.getInstance("SHA256withRSA"); 
sig.initSign(secretKey); //THIS IS THE PROBLEM! 
sig.update(encodedPolicy.getBytes("UTF-8"));   
String signature = new String(Base64.encode(sig.sign())); 

//put the values in the request attributes so we can fetch them from a JSP 
req.setAttribute("policy", encodedPolicy); 
req.setAttribute("signature", signature); 

, 내 문제는 라인

sig.initSign(secretKey); //THIS IS THE PROBLEM! 

secretKey에있는 것은 String입니다. Signature.initSign()PrivateKey 또는 그 자손 오브젝트 중 하나를 필요로합니다. client_secrets.json의 문자열을 Signature.initSign을 전달할 수있는 PrivateKey (또는 파생 된) 객체로 변환하려면 어떻게해야합니까?

도움을 주시면 감사하겠습니다. 감사합니다.

좋아, 여기가 바로 지금입니다. 나는 아래의 제안을 시도하고 모든 설명서는 이 아닌 서비스 계정으로 다운로드 한 client_secrets.json 파일에서 client_secret을 사용하도록 촉구합니다. 게다가, 저는 서비스 계정이 아닌 사용자의 업로드 예제를 만들려고합니다.

나는 다른 페이지에 다음 코드 발견 :

public static String signPolicyDocument(String policyDocument, String secret) {  
try { 
     Mac mac = Mac.getInstance("HmacSHA256"); 
     byte[] secretBytes = secret.getBytes(); 
     SecretKeySpec signingKey = new SecretKeySpec(secretBytes, "HmacSHA256"); 
     mac.init(signingKey); 
     byte[] signedSecretBytes = mac.doFinal(policyDocument.getBytes());   
     return new String(Base64.encode(signedSecretBytes)); 
    } catch (InvalidKeyException e) { 
     throw new RuntimeException(e); 
    } catch (NoSuchAlgorithmException e) { 
     throw new RuntimeException(e); 
    } 

을 그리고 난 결과 양식을 제출 때까지 ... 과정을 통해 나에게 모든 방법을 가져옵니다. 그런 다음 다음과 같은 응답을 받았습니다.

The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method. 

어떤 서명 방법이 필요한가요?

+0

App Engine을 사용하고 있습니까? 질문은 그것을 언급하지는 않지만 그것으로 분류됩니다. –

+0

저는 AppEngine에서 일하고 있습니다. 나는 그 사실을 반영하기 위해 영업 이익을 편집했다. –

답변

0

Appengine에서 GCS로 파일을 업로드하려면 blobstore Api를 사용할 수 있습니다. Using Blobstore with GCS에 설명 된 단계를 따르십시오. 장점은 키에 대해 걱정할 필요가없고 코드가 훨씬 간단하다는 것입니다.

1

여기에 당신이해야 할 생각입니다 :

KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); 
PrivateKey privateKey = keyFactory.generatePrivate(keySpec); 
sig.initSign(privateKey); 

keyBytes 변수가 service account key file in itbyte[] 배열을 포함해야합니다.

+0

응답 해 주셔서 감사합니다. 나는 두 가지 문제를 발견했다. 우선 : sun.misc.BASE64Decoder는 Google App Engine의 Java 런타임 환경에서 지원되지 않습니다. 그래서 이것을 다음과 같이 바꾸려고했습니다 : byte [] encodedKey = Base64.decode (key64); –

+0

그게 작동하지 않았다; "Base64로 인코딩 된 데이터에 잘못된 문자가 있습니다." 그래서 디코딩 단계가 생략되었습니다. 나는 키를 keyspec에 직접 전달했다. 결과는 다음과 같다 java.security.spec.InvalidKeySpecException : java.security.InvalidKeyException : IOException : 조기 EOF를 검출했다 –

+0

네가 맞다면,''Base64.decode''를 사용해야한다. client_secrets.json의 "client_secret"필드를 사용하고 있습니까? 유효한 base64 여야합니다. – jterrace

1

이 문제에 대한 최종 답은 Wargames의 결론과 같습니다. WOPR이 말했듯이, "이상한 게임 ... 승리의 유일한 길은 게임을하지 않는 것이다." 서명 및 정책 문서와 그 모든 쓰레기를 피하고 blobstore를 사용하십시오. 그것은 구현하기가 매우 쉽다

을;

(https://developers.google.com/appengine/docs/java/blobstore/overview#using-blobstore-with-gcs이 참조) 당신과 같이 임시 Blob 저장소 업로드 URL을 만들 때 :

//open the blobstore service and create the upload url 
    BlobstoreService bs = BlobstoreServiceFactory.getBlobstoreService();   
    String uploadUrl = bs.createUploadUrl("/display", 
      UploadOptions.Builder.withGoogleStorageBucketName(bucket)); 

이 방법의 단점은 개체 이름은 당신이 인식 할 수없는 문자열이 될 것입니다. blobstore 뷰어를 열고 blobstore의 파일 이름으로 객체를 볼 수 있지만 GCS에서는 객체 이름이 불투명합니다. (해시, 아마도? 무작위로 할당 된 ID)?

+0

이 접근법을 완벽하게 만드는 방법은 코드에서 객체가 GCS에 저장 될 때 어떤 객체 이름이 사용되는지 지정하는 방법이있는 경우입니다. 아무도 이것을하는 방법을 안다? –

+0

여전히이 접근법을 수정하고 있습니다. 가능한 해결책은 이것을 수행하는 것입니다. –

+0

이 방법을 여전히 개선하고 있습니다. 내가 찾은 가능한 솔루션 1. 업로드 파일 2. 캡처 까다로운 파일 이름 3. 사본 복사본을 만들려면 당신이 4. 듣기 힘든 이름으로 파일을 삭제 원하는 파일 이름에 까다로운 파일 이름이며, 무엇을 x-goog-copy-source 헤더가 추가 된 PUT 요청을 보내면됩니다. https://developers.google.com/storage/docs/reference-headers#xgoogcopy –

관련 문제