我想使用销售伙伴api文档。网。我发现一个参考从下面的网址,但那是使用Java例子编码:https://github.com/amzn/selling-partner-api-docs/blob/main/guides/use-case-guides/feeds-api-use-case-guide-2020-09-04.md#step-2-encrypt-and-upload-the-feed-data
但是我想用.Net编码可以任何一个建议的.Net编码下面的java编码部分
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) {
}
}
}
编辑-----------------------------------------------------
这是我尝试过的,这是我得到的。
第一步
请求URL:https://sellingpartnerapi-na.amazon.com/feeds/2020-09-04/documents 请求正文:{“contentType”:“text/plain;charset=utf-8”}请求头={主机:sellingpartnerapi-na.amazon.com x-amz-date:20210203T120516Z授权:AWS4-HMAC-SHA256凭证=XXXXXXXX/20210203/us-east-1/execute api/AWS4_请求,SignedHeaders=Host;x-amz-date,Signature=XXXX
凭证和签名在合作伙伴门户上创建。
响应步骤1
{"有效载荷":{"加密细节":{"标准":"AES","初始化向量":"TTAVo5bUDNfuk7KPzgmow==","key":"GrpKm3UIvxiM5xUTlzaCC9xJFORMX41chAKUk0G6Cbg="},"feed DocumentId":"amzn1.tortuga.3.9968967c-048c-4e8b-a6c1-ffd764f005d4.T508PJ0OCPKJ3","url":"https://tortuga-prod-na.s3-external-1.amazonaws.com//NinetyDays/amzn1.tortuga.3.9968967c-048c-4e8b-a6c1-ffd764f005d4.T508PJ0OCPKJ3?X-Amz-Algorithm=AWS4-HMAC-SHA256
步骤2:在步骤2中,我使用来自第一步响应的URL,但它没有得到我的结果。
请求网址:
https://tortuga-prod-na.s3-external-1.amazonaws.com//NinetyDays/amzn1.tortuga.3.9968967c-048c-4e8b-a6c1-ffd764f005d4.T508PJ0OCPKJ3?X-Amz算法=AWS4-HMAC-SHA256
看到这里的签名和凭证与我们从步骤1的响应中得到的不同
步骤2的响应
<?xml version="1.0" encoding="UTF-8"?>
-<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
<AWSAccessKeyId>AKIA5U6MO6RANYPNEUPL</AWSAccessKeyId>
<StringToSign>AWS4-HMAC-SHA256 20210203T114111Z 20210203/us-east-1/s3/aws4_request 057d93b83f8254c64b8ffccdfb885b79e5d96c0d2045c27732fc42ae722e335e</StringToSign>
<SignatureProvided>1fd8b69523c06d76664c22c4093be5e8adc187436f7119aa9d4b51302cc8ae84</SignatureProvided>
<StringToSignBytes>41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 0a 32 30 32 31 30 32 30 33 54 31 31 34 31 31 31 5a 0a 32 30 32 31 30 32 30 33 2f 75 73 2d 65 61 73 74 2d 31 2f 73 33 2f 61 77 73 34 5f 72 65 71 75 65 73 74 0a 30 35 37 64 39 33 62 38 33 66 38 32 35 34 63 36 34 62 38 66 66 63 63 64 66 62 38 38 35 62 37 39 65 35 64 39 36 63 30 64 32 30 34 35 63 32 37 37 33 32 66 63 34 32 61 65 37 32 32 65 33 33 35 65</StringToSignBytes>
<CanonicalRequest>PUT //NinetyDays/amzn1.tortuga.3.9968967c-048c-4e8b-a6c1-ffd764f005d4.T508PJ0OCPKJ3 X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA5U6MO6RANYPNEUPL%2F20210203%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210203T114111Z&X-Amz-Expires=300&X-Amz-SignedHeaders=content-type%3Bhost content-type:text/plain; charset=utf-8 host:tortuga-prod-na.s3-external-1.amazonaws.com content-type;host UNSIGNED-PAYLOAD</CanonicalRequest>
<CanonicalRequestBytes>50 55 54 0a 2f 2f 4e 69 6e 65 74 79 44 61 79 73 2f 61 6d 7a 6e 31 2e 74 6f 72 74 75 67 61 2e 33 2e 39 39 36 38 39 36 37 63 2d 30 34 38 63 2d 34 65 38 62 2d 61 36 63 31 2d 66 66 64 37 36 34 66 30 30 35 64 34 2e 54 35 30 38 50 4a 30 4f 43 50 4b 4a 33 0a 58 2d 41 6d 7a 2d 41 6c 67 6f 72 69 74 68 6d 3d 41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 26 58 2d 41 6d 7a 2d 43 72 65 64 65 6e 74 69 61 6c 3d 41 4b 49 41 35 55 36 4d 4f 36 52 41 4e 59 50 4e 45 55 50 4c 25 32 46 32 30 32 31 30 32 30 33 25 32 46 75 73 2d 65 61 73 74 2d 31 25 32 46 73 33 25 32 46 61 77 73 34 5f 72 65 71 75 65 73 74 26 58 2d 41 6d 7a 2d 44 61 74 65 3d 32 30 32 31 30 32 30 33 54 31 31 34 31 31 31 5a 26 58 2d 41 6d 7a 2d 45 78 70 69 72 65 73 3d 33 30 30 26 58 2d 41 6d 7a 2d 53 69 67 6e 65 64 48 65 61 64 65 72 73 3d 63 6f 6e 74 65 6e 74 2d 74 79 70 65 25 33 42 68 6f 73 74 0a 63 6f 6e 74 65 6e 74 2d 74 79 70 65 3a 74 65 78 74 2f 70 6c 61 69 6e 3b 20 63 68 61 72 73 65 74 3d 75 74 66 2d 38 0a 68 6f 73 74 3a 74 6f 72 74 75 67 61 2d 70 72 6f 64 2d 6e 61 2e 73 33 2d 65 78 74 65 72 6e 61 6c 2d 31 2e 61 6d 61 7a 6f 6e 61 77 73 2e 63 6f 6d 0a 0a 63 6f 6e 74 65 6e 74 2d 74 79 70 65 3b 68 6f 73 74 0a 55 4e 53 49 47 4e 45 44 2d 50 41 59 4c 4f 41 44</CanonicalRequestBytes>
<RequestId>48A2CCE3EFA66E89</RequestId>
<HostId>hiZxZwoTgGG4PBvGLchnKV94AA57zzGqnHh5BbTCIAt1ubD47O+8uQMClkDDBoJBgiXgVb57TRE=</HostId>
</Error>
希望这有助于第二步的一些c锐器https://github.com/amzn/selling-partner-api-docs/blob/main/guides/use-case-guides/feeds-api-use-case-guide-2020-09-04.md#step-2-encrypt-and-upload-the-feed-data
假设您已经收到步骤#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="
}
}
将EncryptionDetails.Key和EncryptionDetails.InitializationVector转换为字节,并将平面文件(提要)读入字符串变量。。。
var key = Convert.FromBase64String(createFeedDocumentResponse.Payload.EncryptionDetails.Key);
var iv = Convert.FromBase64String(createFeedDocumentResponse.Payload.EncryptionDetails.InitializationVector);
string feedData = File.ReadAllText(@"C:\temp\AmazonFlatFileTest.txt");
使用上面的密钥和iv变量加密提要...
这里有一个加密和解密的功能,我从微软和稍微改变(信用https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.aescryptoserviceprovider?view=net-5.0)...
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;
}
还有解密函数。。。您需要在第5步解密并处理结果。
编辑:注意,对于较大的输入,Amazon将在响应中使用GZIP压缩(Payload.CompressionAlgorithm)。在DecryptStringFromBytes_Aes方法中包含“compressionAlgorithm”参数。
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;
}
使用EncryptStringToBytes_Aes返回的结果,您现在可以上传到S3URL(在步骤1的有效负载中提供给您)。下面是一个使用Rest Sharp库的示例(从Amazon的C#client示例中的引用判断,一些Amazon员工似乎喜欢使用Rest Sharp库)。
注意:内容类型必须与CreateFeedDocument请求中的内容类型匹配(步骤1)。
这里有一个你可以用来上传到S3的函数...
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
}
快乐的日子...
4.4.1.3 创建/使用伙伴服务 伙伴服务是只能由特定应用使用的服务。 系统由伙伴公司的应用和内部应用组成,用于保护在伙伴应用和内部应用之间处理的信息和功能。 以下是 AIDL 绑定类型服务的示例。 要点(创建服务): 不要定义意图过滤器,并将导出属性显式设置为true。 验证请求应用的证书是否已在自己的白名单中注册。 请勿(无法)通过onBind(onStartCommand, onHandl
4.1.1.3 创建/使用伙伴活动 伙伴活动是只能由特定应用程序使用的活动。 它们在想要安全共享信息和功能的伙伴公司之间使用。 第三方应用程序可能会读取用于启动活动的意图。 因此,如果你将敏感信息放入用于启动活动的意图中,有必要采取对策来确保其无法被恶意第三方读取。 创建伙伴活动的示例代码如下所示。 要点(创建活动): 不要指定taskAffinity。 不要指定launchMode。 不要定义意
有谁知道在内容合作伙伴API中的哪个位置,我们可以找到将用户添加到YouTube CMS的代码。或者这是否可能?
我在使用Byte Buddy时遇到了一个简单的问题,下面是我的代码: 我希望工作并将调用转发到受人尊敬的拦截器实例,但是我得到这个异常: 最奇怪的部分在异常消息的最后: 我做错了什么?
本文向大家介绍如何在PHP中使用AES加密算法加密数据,包括了如何在PHP中使用AES加密算法加密数据的使用技巧和注意事项,需要的朋友参考一下 在研究Discuz 的时候,发现Discuz有一套相当完美的加密算法(相对而言)。这个算法可以将数据加密后,储存起来,到需要用的时候,用之前加密的秘钥将之还原。 除了这个之外,还有AES这个算法能够将数据很好的加密起来,在传输过程中不容易被破解。 在PHP
出身背景 我目前有一个正在工作的C#代码,可以从网页上读取HTTP POST表单提交中的值。看起来是这样的: 我也有工作代码从页面上的文件上传控件读取附件: 显然,最后一段代码还有一点,但我希望它至少能说明我的问题。 我的问题 我现在尝试将这两段代码结合起来。我认为将数据传输对象放在Post函数中一样简单: 这导致在执行HTTP POST时,以下内容返回到浏览器: {“Message”:“此资源不