2014-10-14 3 views
1

Я хочу знать, что, как генерировать signurl с использованием классов хранения Google облако в .netКак подписать URL в .net для Google Cloud Storage

я создал строку в соответствии с требованием

GET 


1388534400 
/bucket/objectname 

но теперь я хочу, чтобы подписать этот адрес с ключом p12, а затем хотите сделать его URL дружественным

Эта библиотека не показывает определенную функцию для него ->https://developers.google.com/resources/api-libraries/documentation/storage/v1/csharp/latest/annotated.html

Таким образом, в основном мне нужно .net дублер Google_Signer_P12 класса PHP

$signer = new Google_Signer_P12(file_get_contents(__DIR__.'/'."final.p12"), "notasecret"); 
$signature = $signer->sign($to_sign); 

ответ

0

Это мой Google код подписавшего, можно сделать его более динамичным в соответствии с их потребностями

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Security.Cryptography; 

using System.Web; 
using System.Security.Cryptography.X509Certificates; 

namespace HHAFSGoogle 
{ 
    static class GoogleSigner 
    { 
     private static string hashAlgo = "SHA256"; 
     public static string ServiceAccountEmail 
     { 
      get 
      { 
       return "[email protected].com"; 
      } 
     } 

     public static string GoogleSecreat 
     { 
      get 
      { 
       return "notasecret"; 
      } 
     } 

     public static string GoogleBucketDir 
     { 
      get 
      { 
       return "MyBucketDirectory"; 
      } 
     } 

     public static string GoogleBucketName 
     { 
      get 
      { 
       return "MyBucket"; 
      } 
     } 

     public static string CertiFilelocation 
     { 
      get 
      { 
       return System.Web.HttpContext.Current.Server.MapPath("p12file.p12"); 
      } 
     } 

     /// <summary> 
     /// Get URL signature 
     /// </summary> 
     /// <param name="base64EncryptedData"></param> 
     /// <param name="certiFilelocation"></param> 
     /// <returns></returns> 
     public static string GetSignature(string base64EncryptedData, string certiFilelocation) 
     { 
      X509Certificate2 certificate = new X509Certificate2(certiFilelocation, GoogleSecreat, X509KeyStorageFlags.Exportable); 

      RSACryptoServiceProvider csp = (RSACryptoServiceProvider)certificate.PrivateKey; 

      RSACryptoServiceProvider privateKey1 = new RSACryptoServiceProvider(); 
      privateKey1.ImportParameters(csp.ExportParameters(true)); 

      csp.ImportParameters(privateKey1.ExportParameters(true)); 

      byte[] data = Encoding.UTF8.GetBytes(base64EncryptedData.Replace("\r", "")); 

      byte[] signature = privateKey1.SignData(data, hashAlgo); 

      bool isValid = privateKey1.VerifyData(data, hashAlgo, signature); 

      if (isValid) 
      { 
       return Convert.ToBase64String(signature); 
      } 
      else 
      { 
       return string.Empty; 
      } 
     } 

     /// <summary> 
     /// Get signed URL by Signature 
     /// </summary> 
     /// <param name="fileName"></param> 
     /// <param name="method"></param> 
     /// <param name="content_type"></param> 
     /// <param name="duration"></param> 
     /// <returns></returns> 
     public static string GetSignedURL(string fileName, string method = "GET", string content_type = "", int duration = 10) 
     { 
      TimeSpan span = (DateTime.UtcNow.AddMinutes(10) - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)); 
      var expires = Math.Round(span.TotalSeconds, 0); 

      // Encode filename, so URL characters like %20 for space could be handled properly in signature 
      fileName = HttpUtility.UrlPathEncode(fileName); 

      // Generate a string to sign 
      StringBuilder sbFileParam = new StringBuilder(); 
      sbFileParam.AppendLine(method); //Could be GET, PUT, DELETE, POST 
      // /* Content-MD5 */ "\n" . 
      sbFileParam.AppendLine(); 
      sbFileParam.AppendLine(content_type); // Type of content you would upload e.g. image/jpeg 
      sbFileParam.AppendLine(expires.ToString());  // Time when link should expire and shouldn't work longer 
      sbFileParam.Append("/" + GoogleBucketName + "/" + fileName); 

      var signature = System.Web.HttpContext.Current.Server.UrlEncode(GetSignature(sbFileParam.ToString(), CertiFilelocation)); 

      return ("https://storage.googleapis.com/MyBucket/" + fileName + 
         "?response-content-disposition=attachment;&GoogleAccessId=" + ServiceAccountEmail + 
         "&Expires=" + expires + "&Signature=" + signature); 
     } 
    } 
} 

и скачать вызов файла выше класса t о получить подписанный URL

GoogleSigner.GetSignedURL(bucketFileName) 

и загрузить вызов файла выше класс, чтобы получить подписанный URL для URL загрузки

GoogleSigner.GetSignedURL(fileName, "PUT", type); 
+0

Какое значение должно быть в 'GoogleSecreat'? Я получаю исключение, когда пытаюсь создать сертификат. – moondaisy

+1

Какая строка кода, о которой вы говорите? Если вы говорите о строке «notasecret», чем ставите ее так, как она есть «notasecret», –

3

Клиент .NET не поддерживает подписание URL-адреса (это XML-только API), так что вам нужно будет либо сделать выноски к инструменту, как gsutil или сгенерировать подпись RSA внутренней к приложению (Signing and verifying signatures with RSA C#)

+0

Вы хотите сказать, что нет альтернативного класса Google_Signer_P12, который есть в PHP, но не в DotNet? –

1

Теперь есть в пакете предварительной версии Google.Cloud.Storage.V1UrlSigner, который может быть использован для для предоставить доступ только для чтения к существующим объектам:

// Create a signed URL which can be used to get a specific object for one hour. 
UrlSigner urlSigner = UrlSigner.FromServiceAccountCredential(credential); 
string url = urlSigner.Sign(
    bucketName, 
    objectName, 
    TimeSpan.FromHours(1), 
    HttpMethod.Get); 

Или написать доступ только поместить конкретное содержание объекта в ведро:

// Create a signed URL which allows the requester to PUT data with the text/plain content-type. 
UrlSigner urlSigner = UrlSigner.FromServiceAccountCredential(credential); 
var destination = "places/world.txt"; 
string url = urlSigner.Sign(
    bucketName, 
    destination, 
    TimeSpan.FromHours(1), 
    HttpMethod.Put, 
    contentHeaders: new Dictionary<string, IEnumerable<string>> { 
     { "Content-Type", new[] { "text/plain" } } 
    }); 

// Upload the content into the bucket using the signed URL. 
string source = "world.txt"; 

ByteArrayContent content; 
using (FileStream stream = File.OpenRead(source)) 
{ 
    byte[] data = new byte[stream.Length]; 
    stream.Read(data, 0, data.Length); 
    content = new ByteArrayContent(data) 
    { 
     Headers = { ContentType = new MediaTypeHeaderValue("text/plain") } 
    }; 
} 

HttpResponseMessage response = await httpClient.PutAsync(url, content); 
1

Я знаю, что вопрос был для P12, но Google привел меня сюда, когда я пытался сделать это для более нового, предпочтительного метода JSON. Я собрал это вместе с другими образцами и сайтами, которые я нашел. Надеюсь, что это поможет сэкономить время.

public string GetSignedURL() 
    { 
     var myObj = "theObject"; 
     var scopes = new string[] { "https://www.googleapis.com/auth/devstorage.read_write" }; 
     var myBucket = "theBucket"; 
     ServiceAccountCredential cred; 

     using (var stream = new FileStream(@"\path to\private-key.json", FileMode.Open, FileAccess.Read)) 
     { 
      cred = GoogleCredential.FromStream(stream) 
            .CreateScoped(scopes) 
            .UnderlyingCredential as ServiceAccountCredential; 
     } 

     var urlSigner = UrlSigner.FromServiceAccountCredential(cred); 

     return urlSigner.Sign(myBucket, myObj, TimeSpan.FromHours(1), HttpMethod.Get); 
    } 

список областей можно найти here

Смежные вопросы