C# 如何使用.net在Amzon中使用销售合作伙伴api加密和上载数据
我想使用.Net的销售合作伙伴api文档。我从下面的url中找到了一个参考,但这是使用Java示例编码: 但是我想用.Net编码可以任何一个建议的.Net编码下面的java编码部分C# 如何使用.net在Amzon中使用销售合作伙伴api加密和上载数据,c#,.net,amazon-web-services,amazon-product-api,C#,.net,Amazon Web Services,Amazon Product Api,我想使用.Net的销售合作伙伴api文档。我从下面的url中找到了一个参考,但这是使用Java示例编码: 但是我想用.Net编码可以任何一个建议的.Net编码下面的java编码部分 import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PipedInputStream; import java.io.PipedOutputStr
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.nio.charset.StandardCharsets;
import com.amazon.spapi.documents.UploadHelper;
import com.amazon.spapi.documents.UploadSpecification;
import com.amazon.spapi.documents.exception.CryptoException;
import com.amazon.spapi.documents.exception.HttpResponseException;
import com.amazon.spapi.documents.impl.AESCryptoStreamFactory;
/* We want to maintain encryption at rest, so do not write unencrypted data to disk. This is bad:
InputStream source = new FileInputStream(new File("/path/to/myFeed.xml"));
Instead, if your data can fit in memory, you can create an InputStream from a String (see encryptAndUpload_fromString()).
Otherwise, you can pipe data into an InputStream using Piped streams (see encryptAndUpload_fromPipedInputStream()).
*/
public class UploadExample {
private final UploadHelper uploadHelper = new UploadHelper.Builder().build();
// key, initializationVector, and url are returned by the createFeedDocument operation.
public void encryptAndUpload_fromString(String key, String initializationVector, String url) {
AESCryptoStreamFactory aesCryptoStreamFactory =
new AESCryptoStreamFactory.Builder(key, initializationVector)
.build();
// This contentType must be the same value that was provided to createFeedDocument.
String contentType = String.format("text/plain; charset=%s", StandardCharsets.UTF_8);
// The character set must be the same one that is specified in contentType.
try
(InputStream source = new ByteArrayInputStream("my feed data".getBytes(StandardCharsets.UTF_8))) {
UploadSpecification uploadSpec =
new UploadSpecification.Builder(contentType, aesCryptoStreamFactory, source, url)
.build();
uploadHelper.upload(uploadSpec);
}
catch (CryptoException | HttpResponseException | IOException e) {
// Handle exception.
}
}
// key, initializationVector, and url are returned from createFeedDocument.
public void encryptAndUpload_fromPipedInputStream(String key, String initializationVector, String url) {
AESCryptoStreamFactory aesCryptoStreamFactory =
new AESCryptoStreamFactory.Builder(key, initializationVector)
.build();
// This contentType must be the same value that was provided to createFeedDocument.
String contentType = String.format("text/plain; charset=%s", StandardCharsets.UTF_8);
try
(PipedInputStream source = new PipedInputStream()) {
new Thread(
new Runnable() {
public void run() {
try
(PipedOutputStream feedContents = new PipedOutputStream(source)) {
// The character set must be the same one that is specified in contentType.
feedContents.write("my feed data\n".getBytes(StandardCharsets.UTF_8));
feedContents.write("more feed data".getBytes(StandardCharsets.UTF_8));
}
catch (IOException e) {
// Handle exception.
}
}
}).start();
UploadSpecification uploadSpec =
new UploadSpecification.Builder(contentType, aesCryptoStreamFactory, source, url)
.build();
uploadHelper.upload(uploadSpec);
}
catch (CryptoException | HttpResponseException | IOException e) {
}
}
}
编辑-----------------------------------------------------
这就是我尝试过的,这就是我得到的
步骤1
请求URL:
请求正文:{“contentType”:“text/plain;charset=utf-8”}
请求头={主机:sellingpartnerapi-na.amazon.com
x-amz-日期:20210203T120516Z
授权:AWS4-HMAC-SHA256凭证=XXXXXXXX/20210203/us-east-1/执行api/AWS4_请求,签名头=主机;x-amz-date,签名=XXXX
凭证和签名在合作伙伴门户上创建
响应步骤1
{“有效载荷”:
{“encryptionDetails”:{“standard”:“AES”,“initializationVector”:“TTAVo5bUDNfuk7KPzgm+ow=”,
“键”:“GrpKm3UIvxiM5xUTlzaCC9xJFORMX41chAKUk0G6Cbg=“”,
“feedDocumentId”:“amzn1.tortuga.3.9968967c-048c-4e8b-a6c1-ffd764f005d4.T508PJ0OCPKJ3”,
“url”:"https://tortuga-prod-na.s3-external-1.amazonaws.com/%2FNinetyDays/amzn1.tortuga.3.9968967c-048c-4e8b-a6c1-ffd764f005d4.T508PJ0OCPKJ3?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20210203T114111Z&X-Amz-SignedHeaders=内容类型%3Bhost&X-Amz-Expires=300&X-Amz-Credential=Akia5U6Mo6Ranypneypl%2F202010203%2Fus-east-1%2Fs3%2Faws4\U请求和X-Amz-Signature=1fd8b69523c06d76664c22c4093be5e8adc187436f7119aa9d4b51302cc8ae84“}
第二步:
在第2步中,我使用来自第一步响应的URL,但它没有得到结果
请求URL:
看到这里的签名和凭证与我们从步骤1的响应中得到的不同
步骤2的响应
希望这有助于第二步中的c锐器 假设您已收到步骤#1的OK响应 步骤1的响应如下所示:
{
"payload":
{
"feedDocumentId":"amzn1.tortuga.3.920614b0-fc4c-4393-b0d9-fff175300000.T29XK4YL08B2VM",
"url":"https://tortuga-prod-na.s3.amazonaws.com/%2FNinetyDays/amzn1.tortuga.3.920614b0-fc4c-4393-b0d9-fff175300000.T29XK4YL08B2VM?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20200919T035824Z&X-Amz-SignedHeaders=<headers>&X-Amz-Expires=300&X-Amz-Credential=<credential>&X-Amz-Signature=<signature>",
"encryptionDetails":
{
"standard":"AES",
"initializationVector":"kF3bZt0FSv6JQEimfEJD8g==",
"key":"5EZo/P06OGF0UAy8QuOnMIaQbkAvYBru6EGsFvK8wJ2="
}
}
使用上面的密钥和iv变量对提要进行加密
这是一个加密和解密函数,我从微软那里得到,并做了一些轻微的修改(归功于)
快乐时光…堆栈溢出不存在,无法为您翻译代码。是的,但这是一个API,那么可能有一种方法可以使VS通过WSDL使代码成为您要查找的代码。任何人都可以告诉我,我们必须在哪个URL上推送此加密数据。在创建IAM时,将其发布到此{访问密钥}/20201013/us-east-1/execute api/aws4_请求删除此错误AuthorizationHeaderMalformed授权标头格式不正确;服务“execute api”不正确。此终结点属于“s3”"很高兴看到你质疑这一点,帮助我节省了很多时间。干杯。我几乎处于相同的情况,但在发送创建提要的第一个请求时,我有以下错误:有人得到了上面的响应吗?如果有,什么操作解决了问题?我在身份验证中遇到了问题,无法进一步。有人可以告诉我我们必须在哪个URL上推送此加密数据。Amazon返回一个预先签名的URL。检查步骤#1感谢您指点我。我向前移动了一个新错误:AuthorizationHeaderMalformedThe authorization header格式不正确;服务“execute api”不正确。此端点属于“s3”.9DD75A286E7422B6rxCxNZ3veB/3ZJ1qrtvleA0JaHTPqprLYe3I5mM/LYLLEVPL6iKGv0irGmV1O9SS4AcmPsM/8/I=已通过的标头:$headers=['内容类型:文本/普通;字符集=utf-8',X-Amz-Content-Sha256:未签名有效载荷',X-Amz-Date:20210105T095435Z','授权:AWS4-HMAC-Sha256凭证={创建IAM时的访问密钥}/20210105/us-east-1/execute api/aws4_请求,SignedHeaders=host;x-amz-access-token;x-amz-content-sha256;x-amz-date,Signature={通过身份验证过程生成}',];我正在使用相同的函数,但无法上载提要详细信息,我正在使用此响应Url作为上载文件的“Url”参数(字节[]字节,字符串Url)函数但获取此错误详细信息时出错:
signaturedesnotmatch
我们计算的请求签名与您提供的签名不匹配。请检查您的密钥和签名方法。
{
"payload":
{
"feedDocumentId":"amzn1.tortuga.3.920614b0-fc4c-4393-b0d9-fff175300000.T29XK4YL08B2VM",
"url":"https://tortuga-prod-na.s3.amazonaws.com/%2FNinetyDays/amzn1.tortuga.3.920614b0-fc4c-4393-b0d9-fff175300000.T29XK4YL08B2VM?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20200919T035824Z&X-Amz-SignedHeaders=<headers>&X-Amz-Expires=300&X-Amz-Credential=<credential>&X-Amz-Signature=<signature>",
"encryptionDetails":
{
"standard":"AES",
"initializationVector":"kF3bZt0FSv6JQEimfEJD8g==",
"key":"5EZo/P06OGF0UAy8QuOnMIaQbkAvYBru6EGsFvK8wJ2="
}
}
var key = Convert.FromBase64String(createFeedDocumentResponse.Payload.EncryptionDetails.Key);
var iv = Convert.FromBase64String(createFeedDocumentResponse.Payload.EncryptionDetails.InitializationVector);
string feedData = File.ReadAllText(@"C:\temp\AmazonFlatFileTest.txt");
private byte[] EncryptStringToBytes_Aes(string plainText, byte[] key, byte[] initializationVector)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (key == null || key.Length <= 0)
throw new ArgumentNullException("Key");
if (initializationVector == null || initializationVector.Length <= 0)
throw new ArgumentNullException("initializationVector");
byte[] encrypted;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = key;
aesAlg.IV = initializationVector;
// Create an encryptor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt, Encoding.UTF8))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return encrypted;
}
private string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] initializationVector, string compressionAlgorithm)
{
// Validate Compression Algorithm
var isGzip = string.Equals(compressionAlgorithm, "GZIP", StringComparison.OrdinalIgnoreCase);
var compressionAlgorithmValid = compressionAlgorithm == null || isGzip;
if (!compressionAlgorithmValid)
{
throw new InvalidOperationException($"Unexpected CompressionAlgorithm encounted. compressionAlgorithm = {compressionAlgorithm}");
}
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (initializationVector == null || initializationVector.Length <= 0)
throw new ArgumentNullException("IV");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = initializationVector;
// Create a decryptor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
if (isGzip)
{
using (var decompressedFileStream = new MemoryStream())
{
using (GZipStream decompressionStream = new GZipStream(csDecrypt, CompressionMode.Decompress))
{
decompressionStream.CopyTo(decompressedFileStream);
decompressedFileStream.Position = 0;
using (var writer = new StreamReader(decompressedFileStream))
{
plaintext = writer.ReadToEnd();
}
}
}
}
else
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt, Encoding.UTF8))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
}
return plaintext;
}
private async Task UploadFile(byte[] bytes, string url)
{
var contentType = "text/plain; charset=utf-8"; // this should be the same as what was used in Step #1 (in the CreateFeedDocument API request)
RestClient restClient = new RestClient(url);
IRestRequest restRequest = new RestRequest(Method.PUT);
restRequest.AddParameter(contentType, bytes, ParameterType.RequestBody);
var response = await restClient.ExecuteAsync(restRequest);
if (!response.IsSuccessful)
{
// your error logic
}
// success. Move to Step #3
}