我一直在尝试使用Amazon SES Https Query API发送电子邮件。 但我不接受我计算并发送给aws的签名。
我收到此错误消息。
<ErrorResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
<Error>
<Type>Sender</Type>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.</Message>
</Error>
<RequestId>c97bd130-24c9-11e6-924a-b59d7ac9182b</RequestId>
</ErrorResponse>
这是我的java代码
public class SendSESMail {
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, IOException, SignatureException {
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
String dateString = format.format(new Date());
final String ENDPOINT = "https://email.us-east-1.amazonaws.com";
final String AWS_ACCESS = "ACCESS_KEY";
final String AWS_SECRET = "SECRET_KEY";
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost(ENDPOINT);
String authString = generateAuthHeader(AWS_ACCESS, AWS_SECRET, dateString);
List<NameValuePair> formVals = new ArrayList<>();
formVals.add(new BasicNameValuePair("Action", "SendRawEmail"));
formVals.add(new BasicNameValuePair("Destination.ToAddresses.member.1", "bhanuka.yd@gmail.com"));
formVals.add(new BasicNameValuePair("Message.Body.Text.Data", "I hope you see the body."));
formVals.add(new BasicNameValuePair("Message.Subject.Data", "This is a Unique Subject"));
formVals.add(new BasicNameValuePair("Source", "test@test.com"));
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(formVals);
post.setHeader("Content-Type", ContentType.APPLICATION_FORM_URLENCODED.toString());
post.setHeader("Date", dateString);
post.setHeader("X-Amzn-Authorization", authString);
post.setEntity(formEntity);
HttpResponse response = httpClient.execute(post);
response.getEntity().writeTo(System.out);
}
public static String generateAuthHeader(String accessKey, String secret, String dateString) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException {
String authHeaderVal = "AWS3-HTTPS AWSAccessKeyId=" + accessKey + ",Algorithm=HmacSHA256,Signature=";
authHeaderVal += generateSignature(dateString, secret);
return authHeaderVal;
}
public static String generateSignature(String message, String secret) throws NoSuchAlgorithmException, InvalidKeyException {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secretKey);
return Base64.encodeBase64URLSafeString(sha256_HMAC.doFinal(message.getBytes()));
}
}
我第一次试用它时,它给了我这个错误
<ErrorResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
<Error>
<Type>Sender</Type>
<Code>ValidationError</Code>
<Message>1 validation error detected: Value null at 'rawMessage' failed to satisfy constraint: Member must not be null</Message>
</Error>
<RequestId>9a986157-24ca-11e6-9864-3fdeb433e3c8</RequestId>
</ErrorResponse>
这是因为签名末尾有一个“=”符号,所以我用了
encodeBase64URLSafeString();
将签名转换为Base64而不是
的方法encodeBase64String();
所以我在这里做错了, 请有人帮帮我 感谢。
答案 0 :(得分:0)
我终于发现我可以使用Signature V4来验证我的HTTP请求。
任何遇到此问题的人都可以按照下面link中的确切流程进行身份验证。
要记住的一点是,请求时间应采用ISO8601格式,UTC格式
这是一种以UTC时区计算当前时间的方法。
public static String getUTCTimeISO8601Format() {
TimeZone timeZone = TimeZone.getTimeZone("UTC");
Calendar calendar = Calendar.getInstance(timeZone);
SimpleDateFormat iso8601Format = new SimpleDateFormat("YYYYMMdd'T'HHmmss'Z'");//ISO8601 B8601DZw.d format
iso8601Format.setTimeZone(timeZone);
return iso8601Format.format(calendar.getTime());
}