【问题现象描述】
上传到OBS中的对象的使用图片转码后显示不正常,经过初步分析发现上传的原图是破损的。
我们建议在上传文件时设置Content-MD5值, 以保证服务端对上传的对象进行完整性校验。进一步分析发现客户端使用Android SDK上传对象,设置Content-MD5值后上传出现如下日志:
ResponseCode: 400, ResponseStatus: Bad Request, XML ErrorMessage:
<?xmlversion="1.0" encoding="UTF-8"standalone="yes"?>
<Error><Code>BadDigest</Code>
<Message>The Content-MD5 you specified didnot match what we received.</Message>
<RequestId>101200000163D6154895799445D7A6F8</RequestId>
……
</Error>
根据此日志表明客户端MD5值与服务端不匹配,两端 MD5值计算方法不一样。
【问题的根因】
在客户端计算Content-MD5值时先计算MD5加密的二进制数组(128位), 再将二进制数组转成了字符串后再进行的Base64编码。
而服务端生成Content-MD5的原理是:先计算MD5加密的二进制数组(128位), 再对这个二进制进行Base64编码。
因此客户端在计算Content-MD5时需要与服务端原理一致,正确的代码(以AndroidSDK为例):
public staticString getMD5File(File file) {
FileInputStream in = null;
try {
in = new FileInputStream(file);
FileChannel channel = in.getChannel();
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0,file.length());
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(buffer);
return Base64.encodeToString(md.digest(), Base64.NO_WRAP);
} catch (NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ignored) {
}
}
}
return "";
}
NO_WRAP参数说明:使用Android SDK Base64编码时要使用NO_WRAP参数
【问题结果】
客户端侧修改Content-MD5方法后问题解决。
上传到OBS中的对象的使用图片转码后显示不正常,经过初步分析发现上传的原图是破损的。
我们建议在上传文件时设置Content-MD5值, 以保证服务端对上传的对象进行完整性校验。进一步分析发现客户端使用Android SDK上传对象,设置Content-MD5值后上传出现如下日志:
ResponseCode: 400, ResponseStatus: Bad Request, XML ErrorMessage:
<?xmlversion="1.0" encoding="UTF-8"standalone="yes"?>
<Error><Code>BadDigest</Code>
<Message>The Content-MD5 you specified didnot match what we received.</Message>
<RequestId>101200000163D6154895799445D7A6F8</RequestId>
……
</Error>
根据此日志表明客户端MD5值与服务端不匹配,两端 MD5值计算方法不一样。
【问题的根因】
在客户端计算Content-MD5值时先计算MD5加密的二进制数组(128位), 再将二进制数组转成了字符串后再进行的Base64编码。
而服务端生成Content-MD5的原理是:先计算MD5加密的二进制数组(128位), 再对这个二进制进行Base64编码。
因此客户端在计算Content-MD5时需要与服务端原理一致,正确的代码(以AndroidSDK为例):
public staticString getMD5File(File file) {
FileInputStream in = null;
try {
in = new FileInputStream(file);
FileChannel channel = in.getChannel();
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0,file.length());
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(buffer);
return Base64.encodeToString(md.digest(), Base64.NO_WRAP);
} catch (NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ignored) {
}
}
}
return "";
}
NO_WRAP参数说明:使用Android SDK Base64编码时要使用NO_WRAP参数
【问题结果】
客户端侧修改Content-MD5方法后问题解决。

