Erstellen einer URL-Signatur mithilfe von C# und dem .NET Framework - Amazon CloudFront

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Erstellen einer URL-Signatur mithilfe von C# und dem .NET Framework

Die C#-Beispiele in diesem Abschnitt implementieren eine Beispielanwendung, die zeigt, wie Signaturen für CloudFront private Distributionen mithilfe von vorgefertigten und benutzerdefinierten Richtlinienanweisungen erstellt werden. Die Beispiele enthalten Dienstprogrammfunktionen auf der Grundlage des AWS SDK für .NET, das in .NET-Anwendungen nützlich sein kann.

Sie können signierte URLs und signierte Cookies auch mithilfe von erstellen. SDK für .NET Schlagen Sie unter den folgenden Themen in der API-Referenz für SDK für .NET nach:

Um den Code herunterzuladen, navigieren Sie zu Signaturcode in C #.

Hinweise
  • Die AmazonCloudFrontCookieSigner Klassen AmazonCloudFrontUrlSigner und die Kurse wurden in ein separates Paket umgezogen. Weitere Informationen zu ihrer Verwendung finden Sie unter CookieSigner und UrlSigner im AWS SDK für .NET (V4) Developer Guide.

  • Das Erstellen einer URL-Signatur ist nur ein Teil der Bereitstellung privater Inhalte über eine signierte URL. Weitere Informationen finden Sie unter Verwenden Sie signierte URLs. Weitere Informationen zur Verwendung signierter Cookies finden Sie unterVerwenden Sie signierte Cookies.

Verwenden Sie einen RSA-Schlüssel im.NET Framework

Um einen RSA-Schlüssel im.NET Framework zu verwenden, müssen Sie die AWS bereitgestellte PEM-Datei in das XML-Format konvertieren, das das.NET Framework verwendet.

Nach der Konvertierung weist die Datei mit dem privaten RSA-Schlüssel das folgende Format auf:

Beispiel : Privater RSA-Schlüssel im XML .NET Framework-Format
<RSAKeyValue> <Modulus> wO5IvYCP5UcoCKDo1dcspoMehWBZcyfs9QEzGi6Oe5y+ewGr1oW+vB2GPB ANBiVPcUHTFWhwaIBd3oglmF0lGQljP/jOfmXHUK2kUUnLnJp+oOBL2NiuFtqcW6h/L5lIpD8Yq+NRHg Ty4zDsyr2880MvXv88yEFURCkqEXAMPLE= </Modulus> <Exponent>AQAB</Exponent> <P> 5bmKDaTz npENGVqz4Cea8XPH+sxt+2VaAwYnsarVUoSBeVt8WLloVuZGG9IZYmH5KteXEu7fZveYd9UEXAMPLE== </P> <Q> 1v9l/WN1a1N3rOK4VGoCokx7kR2SyTMSbZgF9IWJNOugR/WZw7HTnjipO3c9dy1Ms9pUKwUF4 6d7049EXAMPLE== </Q> <DP> RgrSKuLWXMyBH+/l1Dx/I4tXuAJIrlPyo+VmiOc7b5NzHptkSHEPfR9s1 OK0VqjknclqCJ3Ig86OMEtEXAMPLE== </DP> <DQ> pjPjvSFw+RoaTu0pgCA/jwW/FGyfN6iim1RFbkT4 z49DZb2IM885f3vf35eLTaEYRYUHQgZtChNEV0TEXAMPLE== </DQ> <InverseQ> nkvOJTg5QtGNgWb9i cVtzrL/1pFEOHbJXwEJdU99N+7sMK+1066DL/HSBUCD63qD4USpnf0myc24in0EXAMPLE==</InverseQ> <D> Bc7mp7XYHynuPZxChjWNJZIq+A73gm0ASDv6At7F8Vi9r0xUlQe/v0AQS3ycN8QlyR4XMbzMLYk 3yjxFDXo4ZKQtOGzLGteCU2srANiLv26/imXA8FVidZftTAtLviWQZBVPTeYIA69ATUYPEq0a5u5wjGy UOij9OWyuEXAMPLE= </D> </RSAKeyValue>

Signaturmethode für vordefinierte Richtlinien in C#

Der folgende C#-Code erstellt eine signierte URL, die eine vordefinierte Richtlinie verwendet, indem die folgenden Schritte ausgeführt werden:

  • Es wird eine Richtlinienanweisung erstellt.

  • Hasht die Richtlinienanweisung mithilfe von RSA und des privaten Schlüssels SHA1, dessen entsprechender öffentlicher Schlüssel sich in einer vertrauenswürdigen Schlüsselgruppe befindet, und signiert das Ergebnis mit Hilfe von RSA.

  • Die gehashte und signierte Richtlinienanweisung wird in Base64 codiert. Dabei werden Sonderzeichen ersetzt, damit die Zeichenfolge sicher als URL-Anfrageparameter verwendet werden kann.

  • Verkettet die Werte.

Ein Beispiel für die vollständige Implementierung finden Sie unter Signaturcode in C#.

Anmerkung

Das keyId wird zurückgegeben, wenn Sie einen öffentlichen Schlüssel in hochladen. CloudFront Weitere Informationen finden Sie unter 6 &Key-Pair-Id.

Beispiel : In C# festgelegte Methode zum Signieren von Richtlinien
public static string ToUrlSafeBase64String(byte[] bytes) { return System.Convert.ToBase64String(bytes) .Replace('+', '-') .Replace('=', '_') .Replace('/', '~'); } public static string CreateCannedPrivateURL(string urlString, string durationUnits, string durationNumber, string pathToPolicyStmnt, string pathToPrivateKey, string keyId) { // args[] 0-thisMethod, 1-resourceUrl, 2-seconds-minutes-hours-days // to expiration, 3-numberOfPreviousUnits, 4-pathToPolicyStmnt, // 5-pathToPrivateKey, 6-keyId TimeSpan timeSpanInterval = GetDuration(durationUnits, durationNumber); // Create the policy statement. string strPolicy = CreatePolicyStatement(pathToPolicyStmnt, urlString, DateTime.Now, DateTime.Now.Add(timeSpanInterval), "0.0.0.0/0"); if ("Error!" == strPolicy) return "Invalid time frame." + "Start time cannot be greater than end time."; // Copy the expiration time defined by policy statement. string strExpiration = CopyExpirationTimeFromPolicy(strPolicy); // Read the policy into a byte buffer. byte[] bufferPolicy = Encoding.ASCII.GetBytes(strPolicy); // Initialize the SHA1CryptoServiceProvider object and hash the policy data. using (SHA1CryptoServiceProvider cryptoSHA1 = new SHA1CryptoServiceProvider()) { bufferPolicy = cryptoSHA1.ComputeHash(bufferPolicy); // Initialize the RSACryptoServiceProvider object. RSACryptoServiceProvider providerRSA = new RSACryptoServiceProvider(); XmlDocument xmlPrivateKey = new XmlDocument(); // Load your private key, which you created by converting your // .pem file to the XML format that the .NET framework uses. // Several tools are available. xmlPrivateKey.Load(pathToPrivateKey); // Format the RSACryptoServiceProvider providerRSA and // create the signature. providerRSA.FromXmlString(xmlPrivateKey.InnerXml); RSAPKCS1SignatureFormatter rsaFormatter = new RSAPKCS1SignatureFormatter(providerRSA); rsaFormatter.SetHashAlgorithm("SHA1"); byte[] signedPolicyHash = rsaFormatter.CreateSignature(bufferPolicy); // Convert the signed policy to URL-safe base64 encoding and // replace unsafe characters + = / with the safe characters - _ ~ string strSignedPolicy = ToUrlSafeBase64String(signedPolicyHash); // Concatenate the URL, the timestamp, the signature, // and the key pair ID to form the signed URL. return urlString + "?Expires=" + strExpiration + "&Signature=" + strSignedPolicy + "&Key-Pair-Id=" + keyId; } }

Signaturmethode für benutzerdefinierte Richtlinien in C#

Der folgende C#-Code erstellt eine signierte URL, die eine benutzerdefinierte Richtlinie verwendet, indem die folgenden Schritte ausgeführt werden:

  1. Es wird eine Richtlinienanweisung erstellt.

  2. Die Richtlinienanweisung wird in Base64 codiert. Dabei werden Sonderzeichen ersetzt, damit die Zeichenfolge sicher als URL-Anfrageparameter verwendet werden kann.

  3. Hasht die Richtlinienanweisung mithilfe von RSA und des privaten Schlüssels SHA1, dessen entsprechender öffentlicher Schlüssel sich in einer vertrauenswürdigen Schlüsselgruppe befindet, und verschlüsselt das Ergebnis mithilfe von RSA.

  4. Die gehashte Richtlinienanweisung wird in Base64 codiert. Dabei werden Sonderzeichen ersetzt, damit die Zeichenfolge sicher als URL-Anfrageparameter verwendet werden kann.

  5. Verkettet die Werte.

Ein Beispiel für die vollständige Implementierung finden Sie unter Signaturcode in C#.

Anmerkung

Das keyId wird zurückgegeben, wenn Sie einen öffentlichen Schlüssel in hochladen. CloudFront Weitere Informationen finden Sie unter 6 &Key-Pair-Id.

Beispiel : Methode zum Signieren benutzerdefinierter Richtlinien in C#
public static string ToUrlSafeBase64String(byte[] bytes) { return System.Convert.ToBase64String(bytes) .Replace('+', '-') .Replace('=', '_') .Replace('/', '~'); } public static string CreateCustomPrivateURL(string urlString, string durationUnits, string durationNumber, string startIntervalFromNow, string ipaddress, string pathToPolicyStmnt, string pathToPrivateKey, string keyId) { // args[] 0-thisMethod, 1-resourceUrl, 2-seconds-minutes-hours-days // to expiration, 3-numberOfPreviousUnits, 4-starttimeFromNow, // 5-ip_address, 6-pathToPolicyStmt, 7-pathToPrivateKey, 8-keyId TimeSpan timeSpanInterval = GetDuration(durationUnits, durationNumber); TimeSpan timeSpanToStart = GetDurationByUnits(durationUnits, startIntervalFromNow); if (null == timeSpanToStart) return "Invalid duration units." + "Valid options: seconds, minutes, hours, or days"; string strPolicy = CreatePolicyStatement( pathToPolicyStmnt, urlString, DateTime.Now.Add(timeSpanToStart), DateTime.Now.Add(timeSpanInterval), ipaddress); // Read the policy into a byte buffer. byte[] bufferPolicy = Encoding.ASCII.GetBytes(strPolicy); // Convert the policy statement to URL-safe base64 encoding and // replace unsafe characters + = / with the safe characters - _ ~ string urlSafePolicy = ToUrlSafeBase64String(bufferPolicy); // Initialize the SHA1CryptoServiceProvider object and hash the policy data. byte[] bufferPolicyHash; using (SHA1CryptoServiceProvider cryptoSHA1 = new SHA1CryptoServiceProvider()) { bufferPolicyHash = cryptoSHA1.ComputeHash(bufferPolicy); // Initialize the RSACryptoServiceProvider object. RSACryptoServiceProvider providerRSA = new RSACryptoServiceProvider(); XmlDocument xmlPrivateKey = new XmlDocument(); // Load your private key, which you created by converting your // .pem file to the XML format that the .NET framework uses. // Several tools are available. xmlPrivateKey.Load(pathToPrivateKey); // Format the RSACryptoServiceProvider providerRSA // and create the signature. providerRSA.FromXmlString(xmlPrivateKey.InnerXml); RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(providerRSA); RSAFormatter.SetHashAlgorithm("SHA1"); byte[] signedHash = RSAFormatter.CreateSignature(bufferPolicyHash); // Convert the signed policy to URL-safe base64 encoding and // replace unsafe characters + = / with the safe characters - _ ~ string strSignedPolicy = ToUrlSafeBase64String(signedHash); return urlString + "?Policy=" + urlSafePolicy + "&Signature=" + strSignedPolicy + "&Key-Pair-Id=" + keyId; } }

Dienstprogrammmethoden für die Generierung von Signaturen

Mit den folgenden Methoden lassen sich die Richtlinienanweisung aus einer Datei abrufen und Zeitintervalle für die Generierung von Signaturen parsen.

Beispiel : Hilfsmethoden für die Signaturgenerierung
public static string CreatePolicyStatement(string policyStmnt, string resourceUrl, DateTime startTime, DateTime endTime, string ipAddress) { // Create the policy statement. FileStream streamPolicy = new FileStream(policyStmnt, FileMode.Open, FileAccess.Read); using (StreamReader reader = new StreamReader(streamPolicy)) { string strPolicy = reader.ReadToEnd(); TimeSpan startTimeSpanFromNow = (startTime - DateTime.Now); TimeSpan endTimeSpanFromNow = (endTime - DateTime.Now); TimeSpan intervalStart = (DateTime.UtcNow.Add(startTimeSpanFromNow)) - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); TimeSpan intervalEnd = (DateTime.UtcNow.Add(endTimeSpanFromNow)) - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); int startTimestamp = (int)intervalStart.TotalSeconds; // START_TIME int endTimestamp = (int)intervalEnd.TotalSeconds; // END_TIME if (startTimestamp > endTimestamp) return "Error!"; // Replace variables in the policy statement. strPolicy = strPolicy.Replace("RESOURCE", resourceUrl); strPolicy = strPolicy.Replace("START_TIME", startTimestamp.ToString()); strPolicy = strPolicy.Replace("END_TIME", endTimestamp.ToString()); strPolicy = strPolicy.Replace("IP_ADDRESS", ipAddress); strPolicy = strPolicy.Replace("EXPIRES", endTimestamp.ToString()); return strPolicy; } } public static TimeSpan GetDuration(string units, string numUnits) { TimeSpan timeSpanInterval = new TimeSpan(); switch (units) { case "seconds": timeSpanInterval = new TimeSpan(0, 0, 0, int.Parse(numUnits)); break; case "minutes": timeSpanInterval = new TimeSpan(0, 0, int.Parse(numUnits), 0); break; case "hours": timeSpanInterval = new TimeSpan(0, int.Parse(numUnits), 0 ,0); break; case "days": timeSpanInterval = new TimeSpan(int.Parse(numUnits),0 ,0 ,0); break; default: Console.WriteLine("Invalid time units;" + "use seconds, minutes, hours, or days"); break; } return timeSpanInterval; } private static TimeSpan GetDurationByUnits(string durationUnits, string startIntervalFromNow) { switch (durationUnits) { case "seconds": return new TimeSpan(0, 0, int.Parse(startIntervalFromNow)); case "minutes": return new TimeSpan(0, int.Parse(startIntervalFromNow), 0); case "hours": return new TimeSpan(int.Parse(startIntervalFromNow), 0, 0); case "days": return new TimeSpan(int.Parse(startIntervalFromNow), 0, 0, 0); default: return new TimeSpan(0, 0, 0, 0); } } public static string CopyExpirationTimeFromPolicy(string policyStatement) { int startExpiration = policyStatement.IndexOf("EpochTime"); string strExpirationRough = policyStatement.Substring(startExpiration + "EpochTime".Length); char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; List<char> listDigits = new List<char>(digits); StringBuilder buildExpiration = new StringBuilder(20); foreach (char c in strExpirationRough) { if (listDigits.Contains(c)) buildExpiration.Append(c); } return buildExpiration.ToString(); }

Weitere Informationen finden Sie auch unter