Crypto Asset Governance Alliance 中文站

通过Java设置客户端加密实现上传至OSS前已在本地完成数据加密
栏目分类
Crypto Asset Governance Alliance 中文站
Aave中文网
通过Java设置客户端加密实现上传至OSS前已在本地完成数据加密
发布日期:2025-01-02 11:35    点击次数:98
OSS客户端加密是在数据上传至OSS之前,由用户在本地对数据进行加密处理,确保只有密钥持有者才能解密数据,增强数据在传输和存储过程中的安全性。加密方式对于主密钥的使用,目前支持如下两种方式:使用KMS托管用户主密钥 当使用KMS托管用户主密钥用于客户端数据加密时,需要将KMS用户主密钥ID(即CMK ID)传递给SDK。使用用户自主管理的主密钥(RSA) 主密钥信息由用户提供,需要用户将主密钥的公钥、私钥信息当做参数传递给SDK。使用以上两种加密方式能够有效地避免数据泄漏,保护客户端数据安全。即使数据泄漏,其他人也无法解密得到原始数据。加密元数据参数描述是否必须x-oss-meta-client-side-encryption-key加密后的密钥。 经过主密钥加密后再经过base64编码的字符串。是x-oss-meta-client-side-encryption-start随机产生的用于加密数据的初始值 。经过主密钥加密后再经过base64编码的字符串。是x-oss-meta-client-side-encryption-cek-alg数据的加密算法。是x-oss-meta-client-side-encryption-wrap-alg数据密钥的加密算法。是x-oss-meta-client-side-encryption-matdesc主密钥的描述信息。JSON格式。 否x-oss-meta-client-side-encryption-unencrypted-content-length加密前的数据长度。若未指定content-length,则不生成该参数。否x-oss-meta-client-side-encryption-unencrypted-content-md5加密前数据的MD5。若未指定MD5,则不生成该参数。否 x-oss-meta-client-side-encryption-data-size若加密Multipart文件,则需要在init_multipart时传入整个大文件的总大小。是(分片上传)x-oss-meta-client-side-encryption-part-size若加密Multipart文件,则需要在init_multipart时传入分片大小。 是(分片上传)OpenSSL工具说明通过3.x版本的OpenSSL工具默认生成PRIVATE_PKCS8_PEM。如果您需要生成PRIVATE_PKCS1_PEM,需要结合-traditional选项。详情请参见OpenSSL。创建加密客户端<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.62</version> </dependency>如果运行时报java.security.InvalidKeyException: Illegal key size or default parameters异常,则需要补充Oracle的JCE文件,将其部署在JRE的环境中。请根据使用的JDK版本分别下载对应的文件,将其解压后保存在jre/lib/security目录下。JDK6 JCE补充包JDK7 JCE补充包JDK8 JCE补充包创建RSA加密客户端 创建RSA加密客户端之前,需要创建非对称密钥KeyPair对象。OSS Java SDK提供了从PKCS1编码或PKCS8编码的pem格式私钥字符串到RSAPrivateKey对象的转换,以及从X509编码pem格式公钥字符串到RSAPublicKey对象的转换。上述密钥对应的转换方法如下:RSAPrivateKey SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS1(String privateKeyStr);RSAPrivateKey SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS8(String privateKeyStr);RSAPublicKey SimpleRSAEncryptionMaterials.getPublicKeyFromPemX509(String publicKeyStr);创建RSA加密客户端示例代码如下:import com.aliyun.oss.*; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.crypto.SimpleRSAEncryptionMaterials; import java.security.KeyPair; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.HashMap; import java.util.Map; public class Demo { public static void main(String[] args) throws Throwable { // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。 String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 您可以使用以下命令分别生成私钥与公钥pem文件,然后复制pem文件中的字符串到PRIVATE_PKCS1_PEM,PUBLIC_X509_PEM变量中。 // openssl genrsa -out private_key.pem 2048 // openssl rsa -in private_key.pem -out rsa_public_key.pem -pubout // 填写您的RSA私钥字符串,可以使用OpenSSL工具生成。以下为RSA私钥字符串的示例值。 final String PRIVATE_PKCS1_PEM = "-----BEGIN RSA PRIVATE KEY-----\n" + "MIICWwIBAAKBgQCokfiAVXXf5ImFzKDw+XO/UByW6mse2QsIgz3ZwBtMNu59fR5z\n" + "ttSx+8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC5MFO1PByrE/MNd5AAfSVba93\n" + "I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MmR1EKib1Id8hpooY5xaQIDAQAB\n" + "AoGAOPUZgkNeEMinrw31U3b2JS5sepG6oDG2CKpPu8OtdZMaAkzEfVTJiVoJpP2Y\n" + "nPZiADhFW3e0ZAnak9BPsSsySRaSNmR465cG9tbqpXFKh9Rp/sCPo4Jq2n65yood\n" + "JBrnGr6/xhYvNa14sQ6xjjfSgRNBSXD1XXNF4kALwgZyCAECQQDV7t4bTx9FbEs5\n" + "36nAxPsPM6aACXaOkv6d9LXI7A0J8Zf42FeBV6RK0q7QG5iNNd1WJHSXIITUizVF\n" + "6aX5NnvFAkEAybeXNOwUvYtkgxF4s28s6gn11c5HZw4/a8vZm2tXXK/QfTQrJVXp\n" + "VwxmSr0FAajWAlcYN/fGkX1pWA041CKFVQJAG08ozzekeEpAuByTIOaEXgZr5MBQ\n" + "gBbHpgZNBl8Lsw9CJSQI15wGfv6yDiLXsH8FyC9TKs+d5Tv4Cvquk0efOQJAd9OC\n" + "lCKFs48hdyaiz9yEDsc57PdrvRFepVdj/gpGzD14mVerJbOiOF6aSV19ot27u4on\n" + "Td/3aifYs0CveHzFPQJAWb4LCDwqLctfzziG7/S7Z74gyq5qZF4FUElOAZkz123E\n" + "yZvADwuz/4aK0od0lX9c4Jp7Mo5vQ4TvdoBnPuGo****\n" + "-----END RSA PRIVATE KEY-----"; // 填写您的RSA公钥字符串,可以使用OpenSSL工具生成。以下为RSA公钥字符串的示例值。 final String PUBLIC_X509_PEM = "-----BEGIN PUBLIC KEY-----\n" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCokfiAVXXf5ImFzKDw+XO/UByW\n" + "6mse2QsIgz3ZwBtMNu59fR5zttSx+8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC\n" + "5MFO1PByrE/MNd5AAfSVba93I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MnR\n" + "1EKib1Id8hpooY5xaQID****\n" + "-----END PUBLIC KEY-----"; // 创建一个RSA密钥对。 RSAPrivateKey privateKey = SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS1(PRIVATE_PKCS1_PEM); RSAPublicKey publicKey = SimpleRSAEncryptionMaterials.getPublicKeyFromPemX509(PUBLIC_X509_PEM); KeyPair keyPair = new KeyPair(publicKey, privateKey); // 创建主密钥RSA的描述信息,创建后不允许修改。主密钥描述信息和主密钥一一对应。 // 如果所有的Object都使用相同的主密钥,主密钥描述信息可以为空,但后续不支持更换主密钥。 // 如果主密钥描述信息为空,解密时无法判断文件使用的是哪个主密钥进行加密。 // 强烈建议为每个主密钥都配置描述信息,由客户端保存主密钥和描述信息之间的对应关系(服务端不保存两者之间的对应关系)。 Map<String, String> matDesc = new HashMap<String, String>(); matDesc.put("desc-key", "desc-value"); // 创建RSA加密材料。 SimpleRSAEncryptionMaterials encryptionMaterials = new SimpleRSAEncryptionMaterials(keyPair, matDesc); // 如果要下载并解密其他RSA密钥加密的文件,请将其他主密钥及其描述信息添加到加密材料中。 // encryptionMaterials.addKeyPairDescMaterial(<otherKeyPair>, <otherKeyPairMatDesc>); // 创建RSA加密客户端。 OSSEncryptionClient ossEncryptionClient = new OSSEncryptionClientBuilder(). build(endpoint, credentialsProvider, encryptionMaterials); try { // 填写具体业务代码。 } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossEncryptionClient != null) { ossEncryptionClient.shutdown(); } } } }创建KMS加密客户端<dependency> <groupId>com.aliyun.kms</groupId> <artifactId>kms-transfer-client</artifactId> <version>0.1.0</version> <scope>test</scope> </dependency>创建KMS加密客户端示例代码如下:import com.aliyun.oss.*; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.common.utils.BinaryUtil; import com.aliyun.oss.crypto.ContentCryptoMaterialRW; import com.aliyun.oss.crypto.EncryptionMaterials; import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.http.FormatType; import com.aliyuncs.http.MethodType; import com.aliyuncs.http.ProtocolType; import com.aliyuncs.kms.model.v20160120.DecryptRequest; import com.aliyuncs.kms.model.v20160120.DecryptResponse; import com.aliyuncs.kms.model.v20160120.EncryptRequest; import com.aliyuncs.kms.model.v20160120.EncryptResponse; import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.profile.IClientProfile; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.lang.reflect.Field; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; public class Demo { public static void main(String[] args) throws Throwable { // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。 String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 用户主密钥,例如e1935511-cf88-1123-a0f8-1be8d251****。 String cmk = "e1935511-cf88-1123-a0f8-1be8d251****"; // cmk所在的region,例如cn-hangzhou。 String region = "cn-hangzhou"; // 创建主密钥KMS的描述信息,创建后不允许修改。主密钥描述信息、region以及用户主密钥(cmk)是一一对应关系。 // 如果所有的Object都使用相同的cmk,主密钥描述信息可以为空,但后续不支持更换主密钥。 // 如果主密钥描述信息为空,解密时无法判断文件使用的是哪个主密钥进行加密。 // 强烈建议为每个主密钥都配置主密钥描述信息,由客户端保存主密钥和描述信息之间的对应关系(服务端不保存两者之间的对应关系)。 Map<String, String> matDesc = new HashMap<String, String>(); matDesc.put("desc-key", "desc-value"); // 创建KMS加密材料。 KmsEncryptionMaterialsV3 encryptionMaterials = new KmsEncryptionMaterialsV3(region, cmk, matDesc); encryptionMaterials.setKmsCredentialsProvider(credentialsProvider); // 如果要下载并解密其他cmk加密的文件,请将cmk的region名称以及描述信息添加到KMS加密材料中。 // encryptionMaterials.addKmsDescMaterial(<otherKmsRegion>, <otherKmsMatDesc>); // 如果要下载并解密其他cmk加密的文件,且在KMS的账号不同于OSS客户端账号的情况下,请将KMS的region名称、凭证以及描述信息添加到加密材料中。 // encryptionMaterials.addKmsDescMaterial(<otherKmsRegion>, <otherKmsCredentialsProvider>, <otherKmsMatDesc>); // 创建加密客户端。 OSSEncryptionClient ossEncryptionClient = new OSSEncryptionClientBuilder(). build(endpoint, credentialsProvider, encryptionMaterials); try { // 填写具体业务代码。 } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossEncryptionClient != null) { ossEncryptionClient.shutdown(); } } } } class KmsEncryptionMaterialsV3 implements EncryptionMaterials { private static final String KEY_WRAP_ALGORITHM = "KMS/ALICLOUD"; private String region; private String cmk; CredentialsProvider credentialsProvider; private final Map<String, String> desc; private final LinkedHashMap<KmsEncryptionMaterialsV3.KmsClientSuite, Map<String, String>> kmsDescMaterials = new LinkedHashMap<KmsEncryptionMaterialsV3.KmsClientSuite, Map<String, String>>(); public KmsEncryptionMaterialsV3(String region, String cmk) { assertParameterNotNull(region, "kms region"); assertParameterNotNull(cmk, "kms cmk"); this.region = region; this.cmk = cmk; this.desc = new HashMap<String, String>(); } public KmsEncryptionMaterialsV3(String region, String cmk, Map<String, String> desc) { assertParameterNotNull(region, "kms region"); assertParameterNotNull(region, "kms cmk"); this.region = region; this.cmk = cmk; this.desc = (desc == null) ? new HashMap<String, String>() : new HashMap<String, String>(desc); } private final class KmsClientSuite { private String region; private CredentialsProvider credentialsProvider; KmsClientSuite(String region, CredentialsProvider credentialsProvider) { this.region = region; this.credentialsProvider = credentialsProvider; } } public void setKmsCredentialsProvider(CredentialsProvider credentialsProvider) { this.credentialsProvider = credentialsProvider; kmsDescMaterials.put(new KmsEncryptionMaterialsV3.KmsClientSuite(region, credentialsProvider), desc); } private DefaultAcsClient createKmsClient(String region, CredentialsProvider credentialsPorvider) { Credentials credentials = credentialsPorvider.getCredentials(); IClientProfile profile = DefaultProfile.getProfile(region, credentials.getAccessKeyId(), credentials.getSecretAccessKey(), credentials.getSecurityToken()); return new KmsTransferAcsClient(profile); } private EncryptResponse encryptPlainText(String keyId, String plainText) throws ClientException { DefaultAcsClient kmsClient = createKmsClient(region, credentialsProvider); final EncryptRequest encReq = new EncryptRequest(); encReq.setSysProtocol(ProtocolType.HTTPS); encReq.setAcceptFormat(FormatType.JSON); encReq.setSysMethod(MethodType.POST); encReq.setKeyId(keyId); encReq.setPlaintext(plainText); final EncryptResponse encResponse; try { encResponse = kmsClient.getAcsResponse(encReq); } catch (Exception e) { throw new ClientException("the kms client encrypt data failed." + e.getMessage(), e); } return encResponse; } private DecryptResponse decryptCipherBlob(KmsEncryptionMaterialsV3.KmsClientSuite kmsClientSuite, String cipherBlob) throws ClientException { final DefaultAcsClient kmsClient = createKmsClient(kmsClientSuite.region, kmsClientSuite.credentialsProvider); final DecryptRequest decReq = new DecryptRequest(); decReq.setSysProtocol(ProtocolType.HTTPS); decReq.setAcceptFormat(FormatType.JSON); decReq.setSysMethod(MethodType.POST); decReq.setCiphertextBlob(cipherBlob); final DecryptResponse decResponse; try { decResponse = kmsClient.getAcsResponse(decReq); } catch (Exception e) { throw new ClientException("The kms client decrypt data faild." + e.getMessage(), e); } return decResponse; } public void addKmsDescMaterial(String region, Map<String, String> description) { addKmsDescMaterial(region, credentialsProvider, description); } public synchronized void addKmsDescMaterial(String region, CredentialsProvider credentialsProvider, Map<String, String> description) { assertParameterNotNull(region, "region"); assertParameterNotNull(credentialsProvider, "credentialsProvider"); KmsEncryptionMaterialsV3.KmsClientSuite kmsClientSuite = new KmsEncryptionMaterialsV3.KmsClientSuite(region, credentialsProvider); if (description != null) { kmsDescMaterials.put(kmsClientSuite, new HashMap<String, String>(description)); } else { kmsDescMaterials.put(kmsClientSuite, new HashMap<String, String>()); } } private KmsEncryptionMaterialsV3.KmsClientSuite findKmsClientSuiteByDescription(Map<String, String> desc) { if (desc == null) { return null; } for (Map.Entry<KmsEncryptionMaterialsV3.KmsClientSuite, Map<String, String>> entry : kmsDescMaterials.entrySet()) { if (desc.equals(entry.getValue())) { return entry.getKey(); } } return null; } private <K, V> Map.Entry<K, V> getTailByReflection(LinkedHashMap<K, V> map) throws NoSuchFieldException, IllegalAccessException { Field tail = map.getClass().getDeclaredField("tail"); tail.setAccessible(true); return (Map.Entry<K, V>) tail.get(map); } @Override public void encryptCEK(ContentCryptoMaterialRW contentMaterialRW) { try { assertParameterNotNull(contentMaterialRW, "contentMaterialRW"); assertParameterNotNull(contentMaterialRW.getIV(), "contentMaterialRW#getIV"); assertParameterNotNull(contentMaterialRW.getCEK(), "contentMaterialRW#getCEK"); byte[] iv = contentMaterialRW.getIV(); EncryptResponse encryptresponse = encryptPlainText(cmk, BinaryUtil.toBase64String(iv)); byte[] encryptedIV = BinaryUtil.fromBase64String(encryptresponse.getCiphertextBlob()); SecretKey cek = contentMaterialRW.getCEK(); encryptresponse = encryptPlainText(cmk, BinaryUtil.toBase64String(cek.getEncoded())); byte[] encryptedCEK = BinaryUtil.fromBase64String(encryptresponse.getCiphertextBlob()); contentMaterialRW.setEncryptedCEK(encryptedCEK); contentMaterialRW.setEncryptedIV(encryptedIV); contentMaterialRW.setKeyWrapAlgorithm(KEY_WRAP_ALGORITHM); contentMaterialRW.setMaterialsDescription(desc); } catch (Exception e) { throw new ClientException("Kms encrypt CEK IV error. " + "Please check your cmk, region, accessKeyId and accessSecretId." + e.getMessage(), e); } } @Override public void decryptCEK(ContentCryptoMaterialRW contentMaterialRW) { assertParameterNotNull(contentMaterialRW, "ContentCryptoMaterialRW"); assertParameterNotNull(contentMaterialRW.getEncryptedCEK(), "ContentCryptoMaterialRW#getEncryptedCEK"); assertParameterNotNull(contentMaterialRW.getEncryptedIV(), "ContentCryptoMaterialRW#getEncryptedIV"); assertParameterNotNull(contentMaterialRW.getKeyWrapAlgorithm(), "ContentCryptoMaterialRW#getKeyWrapAlgorithm"); if (!contentMaterialRW.getKeyWrapAlgorithm().toLowerCase().equals(KEY_WRAP_ALGORITHM.toLowerCase())) { throw new ClientException( "Unrecognize your object key wrap algorithm: " + contentMaterialRW.getKeyWrapAlgorithm()); } try { KmsEncryptionMaterialsV3.KmsClientSuite kmsClientSuite = findKmsClientSuiteByDescription(contentMaterialRW.getMaterialsDescription()); if (kmsClientSuite == null) { Map.Entry<KmsEncryptionMaterialsV3.KmsClientSuite, Map<String, String>> entry = getTailByReflection(kmsDescMaterials); kmsClientSuite = entry.getKey(); } DecryptResponse decryptIvResp = decryptCipherBlob(kmsClientSuite, BinaryUtil.toBase64String(contentMaterialRW.getEncryptedIV())); byte[] iv = BinaryUtil.fromBase64String(decryptIvResp.getPlaintext()); DecryptResponse decryptCEKResp = decryptCipherBlob(kmsClientSuite, BinaryUtil.toBase64String(contentMaterialRW.getEncryptedCEK())); byte[] cekBytes = BinaryUtil.fromBase64String(decryptCEKResp.getPlaintext()); SecretKey cek = new SecretKeySpec(cekBytes, ""); contentMaterialRW.setCEK(cek); contentMaterialRW.setIV(iv); } catch (Exception e) { throw new ClientException("Unable to decrypt content secured key and iv. " + "Please check your kms region and materails description." + e.getMessage(), e); } } private void assertParameterNotNull(Object parameterValue, String errorMessage) { if (parameterValue == null) throw new IllegalArgumentException(errorMessage); } }以下提供了如何使用用户自主管理的主密钥(RSA)进行普通上传和下载文件、分片上传、范围下载等场景的完整示例。普通上传和下载文件使用主密钥RSA进行普通上传和下载Object示例代码如下:import com.aliyun.oss.*; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.crypto.SimpleRSAEncryptionMaterials; import com.aliyun.oss.model.OSSObject; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.InputStreamReader; import java.security.KeyPair; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.HashMap; import java.util.Map; public class Demo { public static void main(String[] args) throws Throwable { // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。 String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填写Bucket名称,例如examplebucket。 String bucketName = "examplebucket"; // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。 String objectName = "exampleobject.txt"; String content = "Hello OSS!"; // 填写您的RSA私钥字符串,可以使用OpenSSL工具生成。以下为RSA私钥字符串的示例值。 final String PRIVATE_PKCS1_PEM = "-----BEGIN RSA PRIVATE KEY-----\n" + "MIICWwIBAAKBgQCokfiAVXXf5ImFzKDw+XO/UByW6mse2QsIgz3ZwBtMNu59fR5z\n" + "ttSx+8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC5MFO1PByrE/MNd5AAfSVba93\n" + "I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MmR1EKib1Id8hpooY5xaQIDAQAB\n" + "AoGAOPUZgkNeEMinrw31U3b2JS5sepG6oDG2CKpPu8OtdZMaAkzEfVTJiVoJpP2Y\n" + "nPZiADhFW3e0ZAnak9BPsSsySRaSNmR465cG9tbqpXFKh9Rp/sCPo4Jq2n65yood\n" + "JBrnGr6/xhYvNa14sQ6xjjfSgRNBSXD1XXNF4kALwgZyCAECQQDV7t4bTx9FbEs5\n" + "36nAxPsPM6aACXaOkv6d9LXI7A0J8Zf42FeBV6RK0q7QG5iNNd1WJHSXIITUizVF\n" + "6aX5NnvFAkEAybeXNOwUvYtkgxF4s28s6gn11c5HZw4/a8vZm2tXXK/QfTQrJVXp\n" + "VwxmSr0FAajWAlcYN/fGkX1pWA041CKFVQJAG08ozzekeEpAuByTIOaEXgZr5MBQ\n" + "gBbHpgZNBl8Lsw9CJSQI15wGfv6yDiLXsH8FyC9TKs+d5Tv4Cvquk0efOQJAd9OC\n" + "lCKFs48hdyaiz9yEDsc57PdrvRFepVdj/gpGzD14mVerJbOiOF6aSV19ot27u4on\n" + "Td/3aifYs0CveHzFPQJAWb4LCDwqLctfzziG7/S7Z74gyq5qZF4FUElOAZkz123E\n" + "yZvADwuz/4aK0od0lX9c4Jp7Mo5vQ4TvdoBnPuGo****\n" + "-----END RSA PRIVATE KEY-----"; // 填写您的RSA公钥字符串,可以使用OpenSSL工具生成。以下为RSA公钥字符串的示例值。 final String PUBLIC_X509_PEM = "-----BEGIN PUBLIC KEY-----\n" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCokfiAVXXf5ImFzKDw+XO/UByW\n" + "6mse2QsIgz3ZwBtMNu59fR5zttSx+8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC\n" + "5MFO1PByrE/MNd5AAfSVba93I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MnR\n" + "1EKib1Id8hpooY5xaQID****\n" + "-----END PUBLIC KEY-----"; // 创建一个RSA密钥对。 RSAPrivateKey privateKey = SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS1(PRIVATE_PKCS1_PEM); RSAPublicKey publicKey = SimpleRSAEncryptionMaterials.getPublicKeyFromPemX509(PUBLIC_X509_PEM); KeyPair keyPair = new KeyPair(publicKey, privateKey); // 创建主密钥RSA的描述信息。创建后不允许修改。主密钥描述信息和主密钥一一对应。 // 如果所有的object都使用相同的主密钥,主密钥描述信息可以为空,但后续不支持更换主密钥。 // 如果主密钥描述信息为空,解密时无法判断文件使用的是哪个主密钥进行加密。 // 强烈建议为每个主密钥都配置描述信息,由客户端保存主密钥和描述信息之间的对应关系(服务端不保存两者之间的对应关系)。 Map<String, String> matDesc = new HashMap<String, String>(); matDesc.put("desc-key", "desc-value"); // 创建RSA加密材料。 SimpleRSAEncryptionMaterials encryptionMaterials = new SimpleRSAEncryptionMaterials(keyPair, matDesc); // 如果要下载并解密其他RSA密钥加密的文件,请将其他主密钥及其描述信息添加到加密材料中。 // encryptionMaterials.addKeyPairDescMaterial(<otherKeyPair>, <otherKeyPairMatDesc>); // 创建加密客户端。 OSSEncryptionClient ossEncryptionClient = new OSSEncryptionClientBuilder(). build(endpoint, credentialsProvider, encryptionMaterials); try { // 加密上传文件。 ossEncryptionClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes())); // 下载文件时自动解密。 OSSObject ossObject = ossEncryptionClient.getObject(bucketName, objectName); BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent())); StringBuffer buffer = new StringBuffer(); String line; while ((line = reader.readLine()) != null) { buffer.append(line); } reader.close(); // 查看解密后的内容是否与上传的明文一致。 System.out.println("Put plain text: " + content); System.out.println("Get and decrypted text: " + buffer.toString()); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossEncryptionClient != null) { ossEncryptionClient.shutdown(); } } } }分片上传使用主密钥RSA进行分片上传的示例代码如下:import com.aliyun.oss.*; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.crypto.MultipartUploadCryptoContext; import com.aliyun.oss.crypto.SimpleRSAEncryptionMaterials; import com.aliyun.oss.model.*; import java.io.*; import java.security.KeyPair; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Demo { public static void main(String[] args) throws Throwable { // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。 String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填写Bucket名称,例如examplebucket。 String bucketName = "examplebucket"; // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。 String objectName = "exampleobject.txt"; // 文件地址。例如:D:\\localpath\\examplefile.txt String localFile = "D:\\localpath\\examplefile.txt"; // 填写您的RSA私钥字符串,可以使用OpenSSL工具生成。以下为RSA私钥字符串的示例值。 final String PRIVATE_PKCS1_PEM = "-----BEGIN RSA PRIVATE KEY-----\n" + "MIICWwIBAAKBgQCokfiAVXXf5ImFzKDw+XO/UByW6mse2QsIgz3ZwBtMNu59fR5z\n" + "ttSx+8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC5MFO1PByrE/MNd5AAfSVba93\n" + "I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MmR1EKib1Id8hpooY5xaQIDAQAB\n" + "AoGAOPUZgkNeEMinrw31U3b2JS5sepG6oDG2CKpPu8OtdZMaAkzEfVTJiVoJpP2Y\n" + "nPZiADhFW3e0ZAnak9BPsSsySRaSNmR465cG9tbqpXFKh9Rp/sCPo4Jq2n65yood\n" + "JBrnGr6/xhYvNa14sQ6xjjfSgRNBSXD1XXNF4kALwgZyCAECQQDV7t4bTx9FbEs5\n" + "36nAxPsPM6aACXaOkv6d9LXI7A0J8Zf42FeBV6RK0q7QG5iNNd1WJHSXIITUizVF\n" + "6aX5NnvFAkEAybeXNOwUvYtkgxF4s28s6gn11c5HZw4/a8vZm2tXXK/QfTQrJVXp\n" + "VwxmSr0FAajWAlcYN/fGkX1pWA041CKFVQJAG08ozzekeEpAuByTIOaEXgZr5MBQ\n" + "gBbHpgZNBl8Lsw9CJSQI15wGfv6yDiLXsH8FyC9TKs+d5Tv4Cvquk0efOQJAd9OC\n" + "lCKFs48hdyaiz9yEDsc57PdrvRFepVdj/gpGzD14mVerJbOiOF6aSV19ot27u4on\n" + "Td/3aifYs0CveHzFPQJAWb4LCDwqLctfzziG7/S7Z74gyq5qZF4FUElOAZkz123E\n" + "yZvADwuz/4aK0od0lX9c4Jp7Mo5vQ4TvdoBnPuGo****\n" + "-----END RSA PRIVATE KEY-----"; // 填写您的RSA公钥字符串,可以使用OpenSSL工具生成。以下为RSA公钥字符串的示例值。 final String PUBLIC_X509_PEM = "-----BEGIN PUBLIC KEY-----\n" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCokfiAVXXf5ImFzKDw+XO/UByW\n" + "6mse2QsIgz3ZwBtMNu59fR5zttSx+8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC\n" + "5MFO1PByrE/MNd5AAfSVba93I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MnR\n" + "1EKib1Id8hpooY5xaQID****\n" + "-----END PUBLIC KEY-----"; // 创建一个RSA密钥对。 RSAPrivateKey privateKey = SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS1(PRIVATE_PKCS1_PEM); RSAPublicKey publicKey = SimpleRSAEncryptionMaterials.getPublicKeyFromPemX509(PUBLIC_X509_PEM); KeyPair keyPair = new KeyPair(publicKey, privateKey); // 创建主密钥RSA的描述信息,创建后不允许修改。主密钥描述信息和主密钥一一对应。 // 如果所有的Object都使用相同的主密钥,主密钥描述信息可以为空,但后续不支持更换主密钥。 // 如果主密钥描述信息为空,解密时无法判断文件使用的是哪个主密钥进行加密。 // 强烈建议为每个主密钥都配置描述信息,由客户端保存主密钥和描述信息之间的对应关系(服务端不保存两者之间的对应关系)。 Map<String, String> matDesc = new HashMap<String, String>(); matDesc.put("desc-key", "desc-value"); // 创建RSA加密材料。 SimpleRSAEncryptionMaterials encryptionMaterials = new SimpleRSAEncryptionMaterials(keyPair, matDesc); // 如果要下载并解密其他RSA密钥加密的文件,请将其他主密钥及其描述信息添加到加密材料中。 // encryptionMaterials.addKeyPairDescMaterial(<otherKeyPair>, <otherKeyPairMatDesc>); // 创建加密客户端。 OSSEncryptionClient ossEncryptionClient = new OSSEncryptionClientBuilder(). build(endpoint, credentialsProvider, encryptionMaterials); try { // 创建MultipartUploadCryptoContext对象,指定分片大小与文件大小。分片大小需16字节对齐。 File file = new File(localFile); long fileLength = file.length(); final long partSize = 100 * 1024L; // 100K MultipartUploadCryptoContext context = new MultipartUploadCryptoContext(); context.setPartSize(partSize); context.setDataSize(fileLength); // 初始化一个分片上传事件。 InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(bucketName, objectName); // 传入MultipartUploadCryptoContext对象。 InitiateMultipartUploadResult upresult = ossEncryptionClient.initiateMultipartUpload(initiateMultipartUploadRequest, context); String uploadId = upresult.getUploadId(); // 创建PartETag的集合。PartETag由分片的ETag和分片号组成。 List<PartETag> partETags = new ArrayList<PartETag>(); int partCount = (int) (fileLength / partSize); if (fileLength % partSize != 0) { partCount++; } // 遍历分片上传。 for (int i = 0; i < partCount; i++) { long startPos = i * partSize; long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize; InputStream instream = new FileInputStream(file); instream.skip(startPos); UploadPartRequest uploadPartRequest = new UploadPartRequest(); uploadPartRequest.setBucketName(bucketName); uploadPartRequest.setKey(objectName); uploadPartRequest.setUploadId(uploadId); uploadPartRequest.setInputStream(instream); uploadPartRequest.setPartSize(curPartSize); uploadPartRequest.setPartNumber( i + 1); // 传入MultipartUploadCryptoContext对象。 UploadPartResult uploadPartResult = ossEncryptionClient.uploadPart(uploadPartRequest, context); partETags.add(uploadPartResult.getPartETag()); } // 完成分片上传。 CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags); ossEncryptionClient.completeMultipartUpload(completeMultipartUploadRequest); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossEncryptionClient != null) { ossEncryptionClient.shutdown(); } } } }断点续传上传使用主密钥RSA进行断点续传上传的示例代码如下:import com.aliyun.oss.*; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.crypto.SimpleRSAEncryptionMaterials; import com.aliyun.oss.model.*; import java.security.KeyPair; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.HashMap; import java.util.Map; public class Demo { public static void main(String[] args) throws Throwable { // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。 String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填写Bucket名称,例如examplebucket。 String bucketName = "examplebucket"; // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。 String objectName = "exampleobject.txt"; // 文件地址。例如:D:\\localpath\\examplefile.txt String localFile = "D:\\localpath\\examplefile.txt"; // 填写您的RSA私钥字符串,可以使用OpenSSL工具生成。以下为RSA私钥字符串的示例值。 final String PRIVATE_PKCS1_PEM = "-----BEGIN RSA PRIVATE KEY-----\n" + "MIICWwIBAAKBgQCokfiAVXXf5ImFzKDw+XO/UByW6mse2QsIgz3ZwBtMNu59fR5z\n" + "ttSx+8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC5MFO1PByrE/MNd5AAfSVba93\n" + "I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MmR1EKib1Id8hpooY5xaQIDAQAB\n" + "AoGAOPUZgkNeEMinrw31U3b2JS5sepG6oDG2CKpPu8OtdZMaAkzEfVTJiVoJpP2Y\n" + "nPZiADhFW3e0ZAnak9BPsSsySRaSNmR465cG9tbqpXFKh9Rp/sCPo4Jq2n65yood\n" + "JBrnGr6/xhYvNa14sQ6xjjfSgRNBSXD1XXNF4kALwgZyCAECQQDV7t4bTx9FbEs5\n" + "36nAxPsPM6aACXaOkv6d9LXI7A0J8Zf42FeBV6RK0q7QG5iNNd1WJHSXIITUizVF\n" + "6aX5NnvFAkEAybeXNOwUvYtkgxF4s28s6gn11c5HZw4/a8vZm2tXXK/QfTQrJVXp\n" + "VwxmSr0FAajWAlcYN/fGkX1pWA041CKFVQJAG08ozzekeEpAuByTIOaEXgZr5MBQ\n" + "gBbHpgZNBl8Lsw9CJSQI15wGfv6yDiLXsH8FyC9TKs+d5Tv4Cvquk0efOQJAd9OC\n" + "lCKFs48hdyaiz9yEDsc57PdrvRFepVdj/gpGzD14mVerJbOiOF6aSV19ot27u4on\n" + "Td/3aifYs0CveHzFPQJAWb4LCDwqLctfzziG7/S7Z74gyq5qZF4FUElOAZkz123E\n" + "yZvADwuz/4aK0od0lX9c4Jp7Mo5vQ4TvdoBnPuGo****\n" + "-----END RSA PRIVATE KEY-----"; // 填写您的RSA公钥字符串,可以使用OpenSSL工具生成。以下为RSA公钥字符串的示例值。 final String PUBLIC_X509_PEM = "-----BEGIN PUBLIC KEY-----\n" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCokfiAVXXf5ImFzKDw+XO/UByW\n" + "6mse2QsIgz3ZwBtMNu59fR5zttSx+8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC\n" + "5MFO1PByrE/MNd5AAfSVba93I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MnR\n" + "1EKib1Id8hpooY5xaQID****\n" + "-----END PUBLIC KEY-----"; // 创建一个RSA密钥对。 RSAPrivateKey privateKey = SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS1(PRIVATE_PKCS1_PEM); RSAPublicKey publicKey = SimpleRSAEncryptionMaterials.getPublicKeyFromPemX509(PUBLIC_X509_PEM); KeyPair keyPair = new KeyPair(publicKey, privateKey); // 创建主密钥RSA的描述信息,创建后不允许修改。主密钥描述信息和主密钥一一对应。 // 如果所有的Object都使用相同的主密钥,主密钥描述信息可以为空,但后续不支持更换主密钥。 // 如果主密钥描述信息为空,解密时无法判断文件使用的是哪个主密钥进行加密。 // 强烈建议为每个主密钥都配置描述信息,由客户端保存主密钥和描述信息之间的对应关系(服务端不保存两者之间的对应关系)。 Map<String, String> matDesc = new HashMap<String, String>(); matDesc.put("desc-key", "desc-value"); // 创建RSA加密材料。 SimpleRSAEncryptionMaterials encryptionMaterials = new SimpleRSAEncryptionMaterials(keyPair, matDesc); // 如果要下载并解密其他RSA密钥加密的文件,请将其他主密钥及其描述信息添加到加密材料中。 // encryptionMaterials.addKeyPairDescMaterial(<otherKeyPair>, <otherKeyPairMatDesc>); // 创建加密客户端。 OSSEncryptionClient ossEncryptionClient = new OSSEncryptionClientBuilder(). build(endpoint, credentialsProvider, encryptionMaterials); try { // 创建UploadFileRequest对象。 UploadFileRequest uploadFileRequest = new UploadFileRequest(bucketName, objectName); // 设置要上传的文件的路径。 uploadFileRequest.setUploadFile(localFile); // 指定上传的分片大小,范围为100 KB~5 GB,默认为文件大小的1/10000。 uploadFileRequest.setPartSize(100 * 1024); // 开启断点续传,默认关闭。 uploadFileRequest.setEnableCheckpoint(true); // 设置断点记录文件。如未指定,则默认名称为localfile + ".ucp",与localfile同目录。 // 上传过程中的进度信息会保存在该文件中,如果某一分片上传失败,再次上传时会根据文件中记录的点继续上传。上传完成后,该文件会被删除。 uploadFileRequest.setCheckpointFile("test-upload.ucp"); // 开始断点续传上传。 ossEncryptionClient.uploadFile(uploadFileRequest); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossEncryptionClient != null) { ossEncryptionClient.shutdown(); } } } }断点续传下载使用主密钥RSA进行断点续传下载的示例代码如下:import com.aliyun.oss.*; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.crypto.SimpleRSAEncryptionMaterials; import com.aliyun.oss.model.*; import java.security.KeyPair; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.HashMap; import java.util.Map; public class Demo { public static void main(String[] args) throws Throwable { // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。 String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填写Bucket名称,例如examplebucket。 String bucketName = "examplebucket"; // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。 String objectName = "exampleobject.txt"; // 填写您的RSA私钥字符串,可以使用OpenSSL工具生成。以下为RSA私钥字符串的示例值。 final String PRIVATE_PKCS1_PEM = "-----BEGIN RSA PRIVATE KEY-----\n" + "MIICWwIBAAKBgQCokfiAVXXf5ImFzKDw+XO/UByW6mse2QsIgz3ZwBtMNu59fR5z\n" + "ttSx+8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC5MFO1PByrE/MNd5AAfSVba93\n" + "I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MmR1EKib1Id8hpooY5xaQIDAQAB\n" + "AoGAOPUZgkNeEMinrw31U3b2JS5sepG6oDG2CKpPu8OtdZMaAkzEfVTJiVoJpP2Y\n" + "nPZiADhFW3e0ZAnak9BPsSsySRaSNmR465cG9tbqpXFKh9Rp/sCPo4Jq2n65yood\n" + "JBrnGr6/xhYvNa14sQ6xjjfSgRNBSXD1XXNF4kALwgZyCAECQQDV7t4bTx9FbEs5\n" + "36nAxPsPM6aACXaOkv6d9LXI7A0J8Zf42FeBV6RK0q7QG5iNNd1WJHSXIITUizVF\n" + "6aX5NnvFAkEAybeXNOwUvYtkgxF4s28s6gn11c5HZw4/a8vZm2tXXK/QfTQrJVXp\n" + "VwxmSr0FAajWAlcYN/fGkX1pWA041CKFVQJAG08ozzekeEpAuByTIOaEXgZr5MBQ\n" + "gBbHpgZNBl8Lsw9CJSQI15wGfv6yDiLXsH8FyC9TKs+d5Tv4Cvquk0efOQJAd9OC\n" + "lCKFs48hdyaiz9yEDsc57PdrvRFepVdj/gpGzD14mVerJbOiOF6aSV19ot27u4on\n" + "Td/3aifYs0CveHzFPQJAWb4LCDwqLctfzziG7/S7Z74gyq5qZF4FUElOAZkz123E\n" + "yZvADwuz/4aK0od0lX9c4Jp7Mo5vQ4TvdoBnPuGo****\n" + "-----END RSA PRIVATE KEY-----"; // 填写您的RSA公钥字符串,可以使用OpenSSL工具生成。以下为RSA公钥字符串的示例值。 final String PUBLIC_X509_PEM = "-----BEGIN PUBLIC KEY-----\n" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCokfiAVXXf5ImFzKDw+XO/UByW\n" + "6mse2QsIgz3ZwBtMNu59fR5zttSx+8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC\n" + "5MFO1PByrE/MNd5AAfSVba93I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MnR\n" + "1EKib1Id8hpooY5xaQID****\n" + "-----END PUBLIC KEY-----"; // 创建一个RSA密钥对。 RSAPrivateKey privateKey = SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS1(PRIVATE_PKCS1_PEM); RSAPublicKey publicKey = SimpleRSAEncryptionMaterials.getPublicKeyFromPemX509(PUBLIC_X509_PEM); KeyPair keyPair = new KeyPair(publicKey, privateKey); // 创建主密钥RSA的描述信息,创建后不允许修改。主密钥描述信息和主密钥一一对应。 // 如果所有的Object都使用相同的主密钥,主密钥描述信息可以为空,但后续不支持更换主密钥。 // 如果主密钥描述信息为空,解密时无法判断文件使用的是哪个主密钥进行加密。 // 强烈建议为每个主密钥都配置描述信息,由客户端保存主密钥和描述信息之间的对应关系(服务端不保存两者之间的对应关系)。 Map<String, String> matDesc = new HashMap<String, String>(); matDesc.put("desc-key", "desc-value"); // 创建RSA加密材料。 SimpleRSAEncryptionMaterials encryptionMaterials = new SimpleRSAEncryptionMaterials(keyPair, matDesc); // 如果要下载并解密其他RSA密钥加密的文件,请将其他主密钥及其描述信息添加到加密材料中。 // encryptionMaterials.addKeyPairDescMaterial(<otherKeyPair>, <otherKeyPairMatDesc>); // 创建加密客户端。 OSSEncryptionClient ossEncryptionClient = new OSSEncryptionClientBuilder(). build(endpoint, credentialsProvider, encryptionMaterials); try { // 发起下载请求,指定10个任务并发下载,启动断点续传下载。 DownloadFileRequest downloadFileRequest = new DownloadFileRequest(bucketName, objectName); downloadFileRequest.setDownloadFile("<yourDownloadFile>"); downloadFileRequest.setPartSize(1 * 1024 * 1024); downloadFileRequest.setTaskNum(10); downloadFileRequest.setEnableCheckpoint(true); downloadFileRequest.setCheckpointFile("<yourCheckpointFile>"); // 开始断点续传下载。 DownloadFileResult downloadRes = ossEncryptionClient.downloadFile(downloadFileRequest); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossEncryptionClient != null) { ossEncryptionClient.shutdown(); } } } }范围下载使用主密钥RSA对范围下载的文件进行解密的示例代码如下:import com.aliyun.oss.*; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.crypto.SimpleRSAEncryptionMaterials; import com.aliyun.oss.model.*; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.InputStreamReader; import java.security.KeyPair; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.HashMap; import java.util.Map; public class Demo { public static void main(String[] args) throws Throwable { // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。 String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填写Bucket名称,例如examplebucket。 String bucketName = "examplebucket"; // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。 String objectName = "exampleobject.txt"; String content = "test-range-get-content-82042795hlnf12s8yhfs976y2nfoshhnsdfsf235bvsmnhtskbcfd!"; // 填写您的RSA私钥字符串,可以使用OpenSSL工具生成。以下为RSA私钥字符串的示例值。 final String PRIVATE_PKCS1_PEM = "-----BEGIN RSA PRIVATE KEY-----\n" + "MIICWwIBAAKBgQCokfiAVXXf5ImFzKDw+XO/UByW6mse2QsIgz3ZwBtMNu59fR5z\n" + "ttSx+8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC5MFO1PByrE/MNd5AAfSVba93\n" + "I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MmR1EKib1Id8hpooY5xaQIDAQAB\n" + "AoGAOPUZgkNeEMinrw31U3b2JS5sepG6oDG2CKpPu8OtdZMaAkzEfVTJiVoJpP2Y\n" + "nPZiADhFW3e0ZAnak9BPsSsySRaSNmR465cG9tbqpXFKh9Rp/sCPo4Jq2n65yood\n" + "JBrnGr6/xhYvNa14sQ6xjjfSgRNBSXD1XXNF4kALwgZyCAECQQDV7t4bTx9FbEs5\n" + "36nAxPsPM6aACXaOkv6d9LXI7A0J8Zf42FeBV6RK0q7QG5iNNd1WJHSXIITUizVF\n" + "6aX5NnvFAkEAybeXNOwUvYtkgxF4s28s6gn11c5HZw4/a8vZm2tXXK/QfTQrJVXp\n" + "VwxmSr0FAajWAlcYN/fGkX1pWA041CKFVQJAG08ozzekeEpAuByTIOaEXgZr5MBQ\n" + "gBbHpgZNBl8Lsw9CJSQI15wGfv6yDiLXsH8FyC9TKs+d5Tv4Cvquk0efOQJAd9OC\n" + "lCKFs48hdyaiz9yEDsc57PdrvRFepVdj/gpGzD14mVerJbOiOF6aSV19ot27u4on\n" + "Td/3aifYs0CveHzFPQJAWb4LCDwqLctfzziG7/S7Z74gyq5qZF4FUElOAZkz123E\n" + "yZvADwuz/4aK0od0lX9c4Jp7Mo5vQ4TvdoBnPuGo****\n" + "-----END RSA PRIVATE KEY-----"; // 填写您的RSA公钥字符串,可以使用OpenSSL工具生成。以下为RSA公钥字符串的示例值。 final String PUBLIC_X509_PEM = "-----BEGIN PUBLIC KEY-----\n" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCokfiAVXXf5ImFzKDw+XO/UByW\n" + "6mse2QsIgz3ZwBtMNu59fR5zttSx+8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC\n" + "5MFO1PByrE/MNd5AAfSVba93I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MnR\n" + "1EKib1Id8hpooY5xaQID****\n" + "-----END PUBLIC KEY-----"; // 创建一个RSA密钥对。 RSAPrivateKey privateKey = SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS1(PRIVATE_PKCS1_PEM); RSAPublicKey publicKey = SimpleRSAEncryptionMaterials.getPublicKeyFromPemX509(PUBLIC_X509_PEM); KeyPair keyPair = new KeyPair(publicKey, privateKey); // 创建主密钥RSA的描述信息,创建后不允许修改。主密钥描述信息和主密钥一一对应。 // 如果所有的Object都使用相同的主密钥,主密钥描述信息可以为空,但后续不支持更换主密钥。 // 如果主密钥描述信息为空,解密时无法判断文件使用的是哪个主密钥进行加密。 // 强烈建议为每个主密钥都配置描述信息,由客户端保存主密钥和描述信息之间的对应关系(服务端不保存两者之间的对应关系)。 Map<String, String> matDesc = new HashMap<String, String>(); matDesc.put("desc-key", "desc-value"); // 创建RSA加密材料。 SimpleRSAEncryptionMaterials encryptionMaterials = new SimpleRSAEncryptionMaterials(keyPair, matDesc); // 如果要下载并解密其他RSA密钥加密的文件,请将其他主密钥及其描述信息添加到加密材料中。 // encryptionMaterials.addKeyPairDescMaterial(<otherKeyPair>, <otherKeyPairMatDesc>); // 创建加密客户端。 OSSEncryptionClient ossEncryptionClient = new OSSEncryptionClientBuilder(). build(endpoint, credentialsProvider, encryptionMaterials); try { // 加密上传文件。 ossEncryptionClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes())); // 范围下载。 int start = 17; int end = 35; GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objectName); getObjectRequest.setRange(start, end); OSSObject ossObject = ossEncryptionClient.getObject(getObjectRequest); BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent())); StringBuffer buffer = new StringBuffer(); String line; while ((line = reader.readLine()) != null) { buffer.append(line); } reader.close(); // 查看范围下载结果。 System.out.println("Range-Get plain text:" + content.substring(start, end + 1)); System.out.println("Range-Get decrypted text: " + buffer.toString()); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossEncryptionClient != null) { ossEncryptionClient.shutdown(); } } } }相关文档关于客户端加密的完整示例代码,请参见GitHub示例。

  • 上一篇:没有了
  • 下一篇:ADME及药代动力学检测服务