永久在线亚洲观看|亚洲日韩久久AV无码|亚洲无码视频在线免费看|欧美亚洲一区二区三区视频|人人澡人人澡人人看添AV|动漫精品视频一区二区三区|亚洲国产另类久久久精品极度|极品美女熟妇又黄又爽视频一区



  • 滿滿干貨(rsa加密算法數(shù)學原理)rsa加密算法的數(shù)學基礎(chǔ),RSA+AES實現(xiàn)接口驗簽和參數(shù)加密,目前不能發(fā)快遞的地方,

    保健品 nanfang 2023-08-04 02:24 193 0

    1.rsa加密算法原理數(shù)學例子

    RSA非對稱加密RSA是一種常用的非對稱加密算法,加密和加密使用不同的密鑰,常用于要求安全性較高的加密場景,比如接口的驗簽和接口數(shù)據(jù)的加密與解密與非對稱加密算法對比,其安全性較高,但是加密性能卻比較低,不適合高并發(fā)場景,一般只加密少量的數(shù)據(jù)。

    2.rsa加密算法應(yīng)用

    AES對稱加密AES是一種最常mongodbregex見的對稱加密算法(微信小程序加密傳輸就是用這個加密算法的),加密和解密使用的是相同的密鑰其加密性能好,加密解密速度非??欤瑑?nèi)存需求低,適用于經(jīng)常發(fā)送數(shù)據(jù)的場合RSA+AES實現(xiàn)接口驗簽和請求參數(shù)的加密與解密。

    3.rsa加密算法

    背景:做為程序猿,我們經(jīng)常需要在我們自己開發(fā)的系統(tǒng)上,開發(fā)一些接口供第三方調(diào)用,那么這個時候,對我們接口的安全性要求就比較高了,尤其是那種需要傳輸比較私密的信息的時候,其對安全性的要求就更高了實現(xiàn)思路調(diào)用方:

    4.rsa算法是什么加密算法的基礎(chǔ)

    使用AES對稱加密算法對業(yè)務(wù)請求參數(shù)進行加密后傳輸使用RSA非對稱加密算法對AES的密鑰進行公鑰加密后傳輸使用RSA的私鑰對請求參數(shù)mongodbregex進行簽名接收方:獲取到請求參數(shù)后,對參數(shù)進行驗簽和業(yè)務(wù)參數(shù)的解密問題:為什么要對AES的密鑰進行RSA公鑰加密后傳輸?

    5.rsa算法加密和解密例題

    AES是對稱加密算法,加密和解密的密鑰都是同一個,為了防止被別人惡意獲取到該密鑰,然后對我們的業(yè)務(wù)請求參數(shù)進行解密,我們需要將AES密鑰進行非對稱加密后再進行傳輸代碼實現(xiàn)

    6.簡述rsa加密算法的工作原理

    >org.bouncycastlebcpkix-jdk15on1.56

    7.rsa加密解密算法原理

    >com.fasterxml.jackson.corejackson-databind

    8.rsa加密算法流程圖

    2.9.8org.codehaus.jacksmongodbregexon

    9.rsa加密算法是什么密碼

    jackson-core-asl1.8.3請求和接收的實體對象@Data

    10.rsa加密算法原理介紹

    publicclass JsonRequest { //接口id 可空privateString serviceId; //請求唯一id 非空privateString requestId;

    //商戶id 非空privateString appId; //參數(shù)簽名 非空privateString sign; //對稱加密key 非空privateString aseKey;

    //時間戳,精確到毫秒 非空pmongodbregexrivate long timestamp; //請求的業(yè)務(wù)參數(shù)(AES加密后傳入) 可空privateString body; }serviceId:服務(wù)id(接口id)。

    接口設(shè)計分為兩種,一種是所有的調(diào)用方針對類似的業(yè)務(wù),都調(diào)用的是同一接口地址,然后內(nèi)部系統(tǒng)根據(jù)serviceId去判斷具體是要調(diào)用哪個業(yè)務(wù)方法;另一種是針對不同的調(diào)用方,開發(fā)不同的接口,接口地址也是不一樣,那么這個時候就可以不要serviceId這個字段。

    本章是使用第二種方式,所以serviceId可以不要(可空)requestId:請求唯一id方便查詢定位某個請求和防止同個請求多次調(diào)用appmongodbregexId:商戶id,即我們會給調(diào)用方分配一個這樣的id,并且將這個id與調(diào)用方的信息進行關(guān)聯(lián),比如“通過appId查詢出調(diào)用方的加密密鑰等”。

    aseKey:是AES對稱加密的密鑰用于解密業(yè)務(wù)請求參數(shù)這里要先用RSA公鑰對aseKey進行加密后傳輸timestamp:請求時間戳可以用該字段,對請求的時間合法性進行校驗(如:過濾掉請求時間不在當前時間的正負10分鐘范圍內(nèi)的請求)。

    body:請求的業(yè)務(wù)參數(shù)對請求的業(yè)務(wù)參數(shù)AES加密后再賦值A(chǔ)ES工具類publicclassAESUtil{ /** * 加密 * @param content 加密文本 mongodbregex * 。

    @param key 加密密鑰,appSecret的前16位 * @param iv 初始化向量,appSecret的后16位 * @return * @throws Exception */

    publicstatic String encrypt(String content, String key, String iv)throws Exception { byte[] raw = key.getBytes(); SecretKeySpec skeySpec =

    new SecremongodbregextKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //"算法/模式/補碼方式"

    IvParameterSpec ivParam = new IvParameterSpec(iv.getBytes()); //使用CBC模式,需要一個向量iv,可增加加密算法的強度 cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParam);

    byte[] encrypted = cipher.doFinal(content.gemongodbregextBytes()); returnnew BASE64Encoder().encode(encrypted); }

    publicstatic String decrypt(String content, String key, String iv)throws Exception { byte[] raw = key.getBytes(); SecretKeySpec skeySpec =

    new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstancmongodbregexe("AES/CBC/PKCS5Padding "); //"算法/模式/補碼方式"

    IvParameterSpec ivParam = new IvParameterSpec(iv.getBytes()); //使用CBC模式,需要一個向量iv,可增加加密算法的強度 cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParam);

    byte[] encrypted = new BASE64Decoder().decodeBuffer(content); //先用base64解密byte[] original = cipher.doFinalmongodbregex(encrypted);

    returnnew String(original); } publicstaticvoidmain(String[] args)throws Exception { String encrypt = AESUtil.encrypt(

    "你好?。。?!", "1234567890123456", "1234567890123456"); String decrypt = AESUtil.decrypt(encrypt,

    "1234567890123456", "1234567890123456"); mongodbregex System.out.println(decrypt); } RSA工具類 public class

    RSAUtil{ /** * 定義加密方式 */ private final staticString KEY_RSA = "RSA"; /** * 定義簽名算法 */

    private final staticString KEY_RSA_SIGNATURE = "MD5withRSA"; /** mongodbregex* 定義公鑰算法 */ private final

    staticString KEY_RSA_PUBLICKEY = "RSAPublicKey"; /** * 定義私鑰算法 */ private final static

    String KEY_RSA_PRIVATEKEY = "RSAPrivateKey"; static { Security.addProvider(new BouncyCastleProvider()); }

    /** mongodbregex* 初始化密鑰 */ public staticMap init() { Map map =

    null; try { KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_RSA); generator.initialize(

    2048); KeyPair keyPair = generator.generateKeyPair(); // 公鑰 RSAPublicKey publicKemongodbregexy = (RSAPublicKey) keyPair.getPublic();

    // 私鑰 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 將密鑰封裝為map

    map = new HashMap<>(); map.put(KEY_RSA_PUBLICKEY, publicKey); map.put(KEY_RSA_PRIVATEKEY, privateKey); }

    catch (NoSuchAlgorithmException e)mongodbregex { e.printStackTrace(); } return map; }

    /** * 公鑰加密 * * @param data 待加密數(shù)據(jù) * @param key 公鑰 */ public static byte[] encryptByPublicKey(

    String data, String key) { byte[] result = null; try { byte[] bytmongodbregexes = decryptBase64(key);

    // 取得公鑰 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes); KeyFactory factory = KeyFactory.getInstance(KEY_RSA); PublicKey publicKey = factory.generatePublic(keySpec);

    // 對數(shù)據(jù)加密 Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding",mongodbregex "BC"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] encode = cipher.doFinal(data.getBytes());

    // 再進行Base64加密 result = Base64.encode(encode); } catch (Exception e) { e.printStackTrace(); }

    return result; } /** * 私鑰解密 mongodbregex * * @param data 加密數(shù)據(jù) * @param key 私鑰 */

    public staticString decryptByPrivateKey(byte[] data, String key) { String result = null;

    try { // 對私鑰解密 byte[] bytes = decryptBase64(key); // 取得私鑰 PKCS8EncodedKeySpec keySpec =

    new PKCS8EncodedKemongodbregexySpec(bytes); KeyFactory factory = KeyFactory.getInstance(KEY_RSA); PrivateKey privateKey = factory.generatePrivate(keySpec);

    // 對數(shù)據(jù)解密 Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC"); cipher.init(Cipher.DECRYPT_MODE, privateKey);

    // 先Base64解密 bmongodbregexyte[] decoded = Base64.decode(data); result = newString(cipher.doFinal(decoded)); }

    catch (Exception e) { e.printStackTrace(); } return result; } /** * 獲取公鑰 */

    public staticString getPublicKey(Map map) { String str = "";mongodbregex try

    { Key key = (Key) map.get(KEY_RSA_PUBLICKEY); str = encryptBase64(key.getEncoded()); }

    catch (Exception e) { e.printStackTrace(); } return str; } /** * 獲取私鑰 */

    public staticString getPrivateKey(Map map) { mongodbregex String str = ""; try

    { Key key = (Key) map.get(KEY_RSA_PRIVATEKEY); str = encryptBase64(key.getEncoded()); }

    catch (Exception e) { e.printStackTrace(); } return str; } /** * 用私鑰對信息生成數(shù)字簽名 * *

    @param datamongodbregex 加密數(shù)據(jù) * @param privateKey 私鑰 */ public staticString sign(byte[] data,

    String privateKey) { String str = ""; try { // 解密由base64編碼的私鑰 byte[] bytes = decryptBase64(privateKey);

    // 構(gòu)造PKCS8EncodedKeySpec對象 PKCS8EncodedKeySpec pkcs = new PKCS8EmongodbregexncodedKeySpec(bytes);

    // 指定的加密算法 KeyFactory factory = KeyFactory.getInstance(KEY_RSA); // 取私鑰對象 PrivateKey key = factory.generatePrivate(pkcs);

    // 用私鑰對信息生成數(shù)字簽名 Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE); signature.initSign(key); signamongodbregexture.update(data); str = encryptBase64(signature.sign()); }

    catch (Exception e) { e.printStackTrace(); } return str; } /** * 校驗數(shù)字簽名 * *

    @param data 加密數(shù)據(jù) * @param publicKey 公鑰 * @param sign 數(shù)字簽名 * @mongodbregexreturn 校驗成功返回true,失敗返回false */

    public static boolean verify(byte[] data, String publicKey, String sign) { boolean flag =

    false; try { // 解密由base64編碼的公鑰 byte[] bytes = decryptBase64(publicKey);

    // 構(gòu)造X509EncodedKeySpec對象 X509EncodedKeySpec keySpec = new X50mongodbregex9EncodedKeySpec(bytes);

    // 指定的加密算法 KeyFactory factory = KeyFactory.getInstance(KEY_RSA); // 取公鑰對象 PublicKey key = factory.generatePublic(keySpec);

    // 用公鑰驗證數(shù)字簽名 Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE); signature.initVerify(key); sigmongodbregexnature.update(data); flag = signature.verify(decryptBase64(sign)); }

    catch (Exception e) { e.printStackTrace(); } return flag; } /** * BASE64 解密 * *

    @param key 需要解密的字符串 * @return 字節(jié)數(shù)組 */ public stmongodbregexatic byte[] decryptBase64(String key) throws Exception {

    return Base64.decode(key); } /** * BASE64 加密 * * @param key 需要加密的字節(jié)數(shù)組 *

    @return 字符串 */ public staticString encryptBase64(byte[] key) throws Exception { return

    newString(Basemongodbregex64.encode(key)); } /** * 按照紅黑樹(Red-Black tree)的 NavigableMap 實現(xiàn) * 按照字母大小排序 */

    public staticMap sort(Map map) { if (map == null) {

    returnnull; } Map result = new TreeMap<>((Comparator) (o1, o2) -> {

    return o1.compareTo(o2); }); mongodbregex result.putAll(map); return result; } /** * 組合參數(shù) * *

    @param map * @return 如:key1Value1Key2Value2.... */ public staticString groupStringParam(

    Map map) { if (map == null) { returnnull; } StringBmongodbregexuffer sb =

    new StringBuffer(); for (Map.Entry item : map.entrySet()) { if (item.getValue() !=

    null) { sb.append(item.getKey()); if (item.getValue() instanceof List) { sb.append(

    JSON.toJSONString(item.getValue())); } else { sb.append(item.getValuemongodbregex()); } } }

    return sb.toString(); } /** * bean轉(zhuǎn)map * @param obj * @return */ public

    staticMap bean2Map(Object obj) { if (obj == null) { returnnull; }

    Map map = new HashMap<>(); try { mongodbregexBeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

    for (PropertyDescriptor property : propertyDescriptors) { String key = property.getName();

    // 過濾class屬性if (!key.equals("class")) { // 得到prmongodbregexoperty對應(yīng)的getter方法 Method getter = property.getReadMethod();

    Object value = getter.invoke(obj); if (StringUtils.isEmpty(value)) {

    continue; } map.put(key, value); } } }

    catch (Exception e) { e.printStackTrace(); } return mapmongodbregex; } /** * 按照紅黑樹(Red-Black tree)的 NavigableMap 實現(xiàn) * 按照字母大小排序 */

    public staticMap sort(Map map) { if (map == null) {

    returnnull; } Map result = new TreeMap<>((Comparator) (o1, o2) -> {

    return o1.compareTo(o2); }); result.putmongodbregexAll(map); return result; } /** * 組合參數(shù) * *

    @param map * @return 如:key1Value1Key2Value2.... */ public staticString groupStringParam(

    Map map) { if (map == null) { returnnull; } StringBuffer sb =

    new SmongodbregextringBuffer(); for (Map.Entry item : map.entrySet()) { if (item.getValue() !=

    null) { sb.append(item.getKey()); if (item.getValue() instanceof List) { sb.append(

    JSON.toJSONString(item.getValue())); } else { sb.append(item.getValue()); } mongodbregex } }

    return sb.toString(); } /** * bean轉(zhuǎn)map * @param obj * @return */ public

    staticMap bean2Map(Object obj) { if (obj == null) { returnnull; }

    Map map = new HashMap<>(); try { BeanInfo beanInmongodbregexfo = Introspector.getBeanInfo(obj.getClass()); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

    for (PropertyDescriptor property : propertyDescriptors) { String key = property.getName();

    // 過濾class屬性if (!key.equals("class")) { // 得到property對應(yīng)的gettermongodbregex方法 Method getter = property.getReadMethod();

    Object value = getter.invoke(obj); if (StringUtils.isEmpty(value)) {

    continue; } map.put(key, value); } } }

    catch (Exception e) { e.printStackTrace(); } return map; } mongodbregex public

    staticvoid main(String[] args) throws Exception { System.out.println("公鑰加密======私鑰解密");

    String str = "Longer程序員"; byte[] enStr = RSAUtil.encryptByPublicKey(str, publicKey);

    String miyaoStr = HexUtils.bytesToHexString(enStr); byte[] bytes = HexUtils.hexStringToBytesmongodbregex(miyaoStr);

    String decStr = RSAUtil.decryptByPrivateKey(bytes, privateKey); System.out.println("加密前:" + str +

    "\n\r解密后:" + decStr); System.out.println("\n\r"); System.out.println("私鑰簽名======公鑰驗證"

    ); String sign = RSAUtil.sign(str.getBytes(), privateKey); System.mongodbregexout.println("簽名:\n\r"

    + sign); boolean flag = RSAUtil.verify(str.getBytes(), publicKey, sign); System.out.println(

    "驗簽結(jié)果:\n\r" + flag); } jackson工具類import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper;

    import lombok.mongodbregexextern.slf4j.Slf4j; import org.codehaus.jackson.type.TypeReference; import org.springframework.util.StringUtils;

    import java.io.IOException; import java.util.ArrayList; import java.util.List; @Slf4jpublicclassJacksonUtil

    { private static ObjectMapper mongodbregexobjectMapper = new ObjectMapper(); /** * 對象轉(zhuǎn)換成json * *

    @param obj * @param * @return */public static String beanToJson(T obj) {

    if (obj == null) { returnnull; } try { return obj instanceof String ? (String) obj : mongodbregexobjectMapper.writeValueAsString(obj); }

    catch (Exception e) { log.error("beanToJson error", e); e.printStackTrace();

    returnnull; } } /** * 將JSON字符串根據(jù)指定的Class反序列化成Java對象 * * @param json JSON字符串 * 。

    @param pojoClass Java對象Clmongodbregexass * @return 反序列化生成的Java對象 * @throws Exception 如果反序列化過程中發(fā)生錯誤,將拋出異常 */

    public static Object decode(String json, Class pojoClass) throws Exception { try

    { return objectMapper.readValue(json, pojoClass); } catch (Exception e) {

    throw e; } mongodbregex } /** * 將JSON字符串根據(jù)指定的Class反序列化成Java對象 * * @param json JSON字符串 * 。

    @param reference 類型引用 * @return 反序列化生成的Java對象 * @throws Exception 如果反序列化過程中發(fā)生錯誤,將拋出異常 */

    public static Object decode(String json, TypeReference reference) throws Excmongodbregexeption { try {

    return objectMapper.readValue(json, reference.getClass()); } catch (Exception e) {

    throw e; } } /** * 將Java對象序列化成JSON字符串 * * @param obj 待序列化生成JSON字符串的Java對象 * 。

    @return JSON字符串 * @throws Exception 如果序列化過程中發(fā)生mongodbregex錯誤,將拋出異常 */public static String encode(Object obj) throws Exception {

    try { return objectMapper.writeValueAsString(obj); } catch (Exception e) {

    throw e; } } /** * 對象轉(zhuǎn)換成格式化的json * * @param obj * @param *

    @return mongodbregex */public static String beanToJsonPretty(T obj) { if (obj == null) {

    returnnull; } try { return obj instanceof String ? (String) obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj); }

    catch (Exception e) { log.error("beanToJsmongodbregexonPretty error", e); e.printStackTrace();

    returnnull; } } /** * 將json轉(zhuǎn)換成對象Class * * @param str * @param clazz *

    @param * @return */public static T jsonToBean(String str, Class clazz) {

    if (StringUtils.isEmpty(str)mongodbregex || clazz == null) { returnnull; } try {

    return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz); } catch (Exception e) { log.error(

    "jsonToBean error", e); e.printStackTrace(); returnnull; } }

    /** mongodbregex* 將json轉(zhuǎn)換為對象集合 * * @param str * @param clazz * @param * @return

    */public static List jsonToBeanList(String str, Class clazz) { if (StringUtils.isEmpty(str) || clazz ==

    null) { returnnull; } JavaType javaType = getCollectionType(ArmongodbregexrayList.class

    , clazz);try { return objectMapper.readValue(str, javaType); } catch (IOException e) { log.error(

    "jsonToBeanList error", e); e.printStackTrace(); returnnull; } }

    public static JavaType getCollectionType(Class collectionClass, Class.mongodbregex.. elementClasses) {

    return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses); } }

    加密解密驗簽名流程演示 public classRequestTest{ public staticvoid main(String[] args) { /****先給調(diào)用方分配一組RSA密鑰和一個appId****/

    //初始化RSA密鑰Map init = RSAUtil.initmongodbregex(); //私鑰String privateKey = RSAUtil.getPrivateKey(init);

    //公鑰String publicKey = RSAUtil.getPublicKey(init); //appId,32位的uuidString appId = getUUID32();

    /****先給調(diào)用方分配一組RSA密鑰和一個appId****//*****調(diào)用方(請求方)*****///業(yè)務(wù)參數(shù)Map businessParams = new HashMap<>(); businessParams.put(

    "name","Lonmongodbregexger"); businessParams.put("job","程序猿"); businessParams.put("hobby","打籃球"); JsonRequest jsonRequest =

    new JsonRequest(); jsonRequest.setRequestId(getUUID32()); jsonRequest.setAppId(appId); jsonRequest.setTimestamp(System.currentTimeMillis());

    //使用appId的前mongodbregex16位作為AES密鑰,并對密鑰進行rsa公鑰加密String aseKey = appId.substring(0, 16); byte[] enStr = RSAUtil.encryptByPublicKey(aseKey, publicKey);

    String aseKeyStr = HexUtils.bytesToHexString(enStr); jsonRequest.setAseKey(aseKeyStr);

    //請求的業(yè)務(wù)參數(shù)進行加密String body = ""; try { body = AESUtil.encrymongodbregexpt(JacksonUtil.beanToJson(businessParams), aseKey, appId.substring(

    16)); } catch (Exception e) { thrownew RuntimeException("報文加密異常", e); } jsonRequest.setBody(body);

    //簽名Map paramMap = RSAUtil.bean2Map(jsonRequest); paramMap.remove("sign");

    // 參數(shù)排序Map sortedMap mongodbregex= RSAUtil.sort(paramMap); // 拼接參數(shù):key1Value1key2Value2String

    urlParams = RSAUtil.groupStringParam(sortedMap); //私鑰簽名String sign = RSAUtil.sign(HexUtils.hexStringToBytes(urlParams), privateKey); jsonRequest.setSign(sign);

    /*****調(diào)用方(請求方)*****//*****接收方(自己的系統(tǒng))*****///參數(shù)判空(略)//appImongodbregexd校驗(略)//本條請求的合法性校驗《唯一不重復(fù)請求;時間合理》(略)//驗簽Map

    , Object> paramMap2 = RSAUtil.bean2Map(jsonRequest); paramMap2.remove("sign"); //參數(shù)排序

    Map sortedMap2 = RSAUtil.sort(paramMap2); //拼接參數(shù):key1Value1key2Value2String urlParams2 = RSAUtil.groupStringParam(sortedMap2);

    //簽名驗證 boolean mongodbregexverify = RSAUtil.verify(HexUtils.hexStringToBytes(urlParams2), publicKey, jsonRequest.getSign());

    if (!verify) { thrownew RuntimeException("簽名驗證失敗"); } //私鑰解密,獲取aseKeyString

    aseKey2 = RSAUtil.decryptByPrivateKey(HexUtils.hexStringToBytes(jsonRequest.getAseKey()), privateKey);

    ifmongodbregex (!StringUtils.isEmpty(jsonRequest.getBody())) { // 解密請求報文String requestBody = "";

    try { requestBody = AESUtil.decrypt(jsonRequest.getBody(), aseKey, jsonRequest.getAppId().substring(

    16)); } catch (Exception e) { thrownew RuntimeException("請求參數(shù)解密異常"); } mongodbregex System.out.println(

    "業(yè)務(wù)參數(shù)解密結(jié)果:"+requestBody); } /*****接收方(自己的系統(tǒng))*****/ } public staticString getUUID32() {

    String uuid = UUID.randomUUID().toString(); uuid = uuid.replace("-", ""); return uuid; } }

    執(zhí)行結(jié)果:業(yè)務(wù)參數(shù)解密結(jié)果:{"name":"Longer","job":"程mongodbregex序猿","hobby":"打籃球"} 到此,調(diào)用方要做的和接收方做的其實都已經(jīng)清楚了調(diào)用方:1.業(yè)務(wù)參數(shù)進行AES對稱加密2.AES密鑰進行RSA非對稱加密

    3.使用RSA生成簽名接收方:驗證簽名AES密鑰解密業(yè)務(wù)參數(shù)解密請求參數(shù)的統(tǒng)一處理上面講到,我們接受的請求對象是JsonRequst對象,里面除了body成員變量是跟業(yè)務(wù)相關(guān),其他成員變量(sericeId,appId等)都是與業(yè)務(wù)不相關(guān)的。

    那么,如果我們在controller層用JsonRequest對象去接收請求參數(shù)的話,其實是不那么規(guī)范的那么我們能不能對請求參數(shù)進行統(tǒng)一處理,使得傳到controller層的參數(shù)只是跟業(yè)mongodbregex務(wù)相關(guān)的參數(shù),并且在controller層也無需關(guān)注加密解密和驗簽的東西。

    實現(xiàn)方法:使用過濾器,攔截請求,并對請求參數(shù)進行統(tǒng)一處理(加密解密,驗簽等)自定義request對象(新增類繼承HttpServletRequestWrapper類),對請求參數(shù)進行過濾處理,使得controller只接受業(yè)務(wù)參數(shù)。

    問題:為什么需要自定義request對象?因為獲取post請求傳遞的json對象,需要用request對象流取獲取,而一旦我們調(diào)用了request.getInputStream()方法后,流將會自動關(guān)閉,那么到了我們的controller層就不能再獲取到請求參數(shù)了。

    自定義request對象immongodbregexport javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.ServletRequest;

    import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import

    java.io.*; import java.nio.charset.Charset; mongodbregex publicclassRequestWrapperextendsHttpServletRequestWrapper

    { privatebyte[] body; publicRequestWrapper(HttpServletRequest request)throws IOException {

    super(request); String sessionStream = getBodyString(request); body = sessionStream.getBytes(Charset.forName(

    "UmongodbregexTF-8")); } public String getBodyString(){ returnnew String(body, Charset.forName("UTF-8"

    )); } publicvoidsetBodyString(byte[] bodyByte){ body = bodyByte; } /** * 獲取請求Body * *

    @param request * @return mongodbregex */public String getBodyString(final ServletRequest request){ StringBuilder sb =

    new StringBuilder(); InputStream inputStream = null; BufferedReader reader = null;

    try { inputStream = cloneInputStream(request.getInputStream()); reader = new BufferedReader(

    nemongodbregexw InputStreamReader(inputStream, Charset.forName("UTF-8"))); String line = "";

    while ((line = reader.readLine()) != null) { sb.append(line); } }

    catch (IOException e) { e.printStackTrace(); } finally { if (inputStream !=

    null) { try { mongodbregex inputStream.close(); } catch (IOException e) { e.printStackTrace(); } }

    if (reader != null) { try { reader.close(); } catch

    (IOException e) { e.printStackTrace(); } } }

    return sb.toString(); } /mongodbregex** * Description: 復(fù)制輸入流

    * * @param inputStream *

    @return

    */public InputStream cloneInputStream(ServletInputStream inputStream){ ByteArrayOutputStream byteArrayOutputStream =

    new ByteArrayOutputStream(); byte[] buffer = newbyte[1024]; int len; try {

    while ((len mongodbregex= inputStream.read(buffer)) > -1) { byteArrayOutputStream.write(buffer, 0

    , len); } byteArrayOutputStream.flush(); } catch (IOException e) { e.printStackTrace(); } InputStream byteArrayInputStream =

    new ByteArrayInputStream(byteArrayOutputStream.mongodbregextoByteArray()); return byteArrayInputStream; }

    @Overridepublic BufferedReader getReader()throws IOException { returnnew BufferedReader(new InputStreamReader(getInputStream())); }

    @Overridepublic ServletInputStream getInputStream()throws IOException { final BytemongodbregexArrayInputStream bais =

    new ByteArrayInputStream(body); returnnew ServletInputStream() { @Overridepublic

    intread()throws IOException { return bais.read(); } @Override

    publicbooleanisFinished(){ returnfalse; } @Overridepublicboolean

    isReamongodbregexdy(){ returnfalse; } @OverridepublicvoidsetReadListener

    (ReadListener readListener){ } }; } }自定義過濾器@Slf4jpublicclass OutRequestFilter

    extends OncePerRequestFilter { @SneakyThrows@Overrideprotectedvoid doFilterInternal(ServletRequest smongodbregexervletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException { RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class); HttpServletRequest request = (HttpServletRequest) servletRequest;

    String requestURL = request.getRequestURI(); log.info("請求mongodbregex路徑:" + requestURL); String method = request.getMethod();

    if (!"POST".equals(method)) { thrownew RuntimeException("暫不支持" + method + "請求方式"); }

    //獲取請求參數(shù) RequestWrapper requestWrapper = new RequestWrapper(request); String bodyString = requestWrapper.getBodyString()mongodbregex;

    if (StringUtils.isEmpty(bodyString)) { thrownew RuntimeException("請求體不能為空"); } log.info(

    "請求參數(shù):" + bodyString); JsonRequest jsonRequest = JacksonUtil.jsonToBean(bodyString, JsonRequest.class);

    //step0 參數(shù)合法性校驗(非空判斷等) parameterValidate(jsonRequest); //stemongodbregexp1 判斷請求合法性1.不允許重復(fù)請求(通過請求唯一id判斷)2.不允許請求時間與當前時間差距過大(正負10分鐘)。

    long currentTime = System.currentTimeMillis(); long subTime = currentTime - jsonRequest.getTimestamp(); long tenMinuteMs =

    10 * 60 * 1000; if (subTime tenMinuteMs) { thrownew RuntimeException(

    "請求異常,請求時間異常"); mongodbregex } String requestUUIDKey = MessageFormat.format(RedisConstant.REQUEST_UUID, jsonRequest.getRequestId());

    Object requestFlag = redisUtil.get(requestUUIDKey); if (!StringUtils.isEmpty(requestFlag)) {

    thrownew RuntimeException("請求異常,重復(fù)的請求"); } redisUtil.set(requestUUIDmongodbregexKey, JacksonUtil.beanToJson(jsonRequest),

    15 * 60); //step2 參數(shù)解密,簽名校驗,參數(shù)過濾和傳遞 Map paramMap = RSAUtil.bean2Map(jsonRequest); paramMap.remove(

    "sign"); //根據(jù)appkey獲取rsa密鑰String appIdKey = MessageFormat.format(RedisConstant.REQUEST_APPID, jsonRequest.getAppId());

    Object ob =mongodbregex redisUtil.get(appIdKey); if (StringUtils.isEmpty(ob)) { thrownew RuntimeException(

    "找不到指定的appid"); } String jsonString = (String) ob; JSONObject jsonObject = JSONObject.parseObject(jsonString);

    //rsa公鑰String publicKey = jsonObject.getString("publicKey"); mongodbregex //rsa私鑰String privateKey = jsonObject.getString(

    "privateKey"); //參數(shù)排序 Map sortedMap = RSAUtil.sort(paramMap);

    //拼接參數(shù):key1Value1key2Value2String urlParams = RSAUtil.groupStringParam(sortedMap); //簽名驗證boolean

    verify = RSAUtil.verify(HexUtils.hexStringToBytes(urlParams), publicKmongodbregexey, jsonRequest.getSign());

    if (!verify) { thrownew RuntimeException("簽名驗證失敗"); } //私鑰解密,獲取aseKeyString

    aseKey = RSAUtil.decryptByPrivateKey(HexUtils.hexStringToBytes(jsonRequest.getAseKey()), privateKey);

    if (!StringUtils.isEmpty(jsonRequest.getBody())) { // 解密請求報文Strinmongodbregexg body = "";

    try { body = AESUtil.decrypt(jsonRequest.getBody(), aseKey, jsonRequest.getAppId().substring(

    16)); } catch (Exception e) { log.error("請求參數(shù)解密異常:",e); throw

    new RuntimeException("請求參數(shù)解密異常"); } //報文傳遞至controller層 requestWrapper.setBodySmongodbregextring(body.getBytes(Charset.forName(

    "UTF-8"))); } //將request傳遞下去 filterChain.doFilter(requestWrapper, servletResponse); }

    privatevoid parameterValidate(JsonRequest jsonRequest) { if (StringUtils.isEmpty(jsonRequest.getAppId())) {

    thrownew RuntimeException("參數(shù)異常,mongodbregexappId不能為空"); } if (StringUtils.isEmpty(jsonRequest.getAseKey())) {

    thrownew RuntimeException("參數(shù)異常,aseKey不能為空"); } if (StringUtils.isEmpty(jsonRequest.getRequestId())) {

    thrownew RuntimeException("參數(shù)異常,requestId不能為空"); } if (StringUtils.isEmpty(jsonRequemongodbregexst.getSign())) {

    thrownew RuntimeException("參數(shù)異常,sign不能為空"); } if (jsonRequest.getTimestamp() == 0l) {

    thrownew RuntimeException("參數(shù)異常,timestamp不能為空"); } } }完整流程演示調(diào)用方HttpClientUtils類 public class

    HttpClientUtils{ private static Logger logger = Lmongodbregexogger.getLogger(HttpClientUtils.class.getName()); public

    staticString doPostJson(String url, String json) { // 創(chuàng)建Httpclient對象 CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response =

    null; String resultString = ""; mongodbregextry { // 創(chuàng)建Http Post請求 HttpPost httpPost =

    new HttpPost(url); // 創(chuàng)建請求內(nèi)容 StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON); httpPost.setEntity(entity);

    // 執(zhí)行http請求 response = httpClient.execute(httpPost); resultString = EnmongodbregextityUtils.toString(response.getEntity(),

    "utf-8"); } catch (Exception e) { resultString = e.getMessage(); logger.info(

    "http訪問失?。? + e); } finally { try { response.close(); }

    catch (IOException e) { logger.info("response關(guān)閉失敗:" + e); mongodbregex } }

    return resultString; } /** * post請求,簽名和報文加密 * * @param url 請求地址 *

    @param json 請求json參數(shù) * @param appId 商戶id * @param publicKey rsa公鑰 * @param

    privateKey rsa私鑰 * @return */ public staticString mongodbregexdoPostJsonForSign(String url, String json,

    String appId, String publicKey, String privateKey) { String aseKey = appId.substring(0, 16); JsonRequest jsonRequest =

    new JsonRequest(); jsonRequest.setRequestId(getUUID32()); jsonRequest.setAppId(appId); jsonRequest.smongodbregexetTimestamp(System.currentTimeMillis());

    //aseKey 加密 logger.info("開始aseKey加密...."); byte[] enStr = RSAUtil.encryptByPublicKey(aseKey, publicKey);

    String aseKeyStr = HexUtils.bytesToHexString(enStr); jsonRequest.setAseKey(aseKeyStr);

    //請求參數(shù)進行加密String body = ""; try { mongodbregex logger.info("開始請求參數(shù)加密...."); body = AESUtil.encrypt(json, aseKey, appId.substring(

    16)); } catch (Exception e) { logger.info("報文加密異常:" + e); thrownew UncheckedException(

    "報文加密異常", e); } jsonRequest.setBody(body); Map paramMap = RSAUtil.bean2mongodbregexMap(jsonRequest); paramMap.remove(

    "sign"); // 參數(shù)排序Map sortedMap = RSAUtil.sort(paramMap); // 拼接參數(shù):key1Value1key2Value2

    String urlParams = RSAUtil.groupStringParam(sortedMap); //私鑰簽名 logger.info("開始參數(shù)簽名...."

    ); String sign = RSAUtil.sign(HexUtils.hexStrinmongodbregexgToBytes(urlParams), privateKey); jsonRequest.setSign(sign);

    String requestParams = JacksonUtil.beanToJson(jsonRequest); logger.info("發(fā)起請求....");

    String result = doPostJson(url, requestParams); return result; } public staticString

    getUUID32() { String uumongodbregexid = UUID.randomUUID().toString(); uuid = uuid.replace("-", ""

    ); return uuid; } } 需要傳遞的業(yè)務(wù)參數(shù)對象@DatapublicclassRequestDto{ private String name;

    privateint age; private String hobby; }發(fā)送請求publicstaticvoid main(String[] args) { //請mongodbregex求地址String

    url = "http://127.0.0.1:8888/test"; RequestDto requestDto = new RequestDto(); requestDto.setAge(

    100); requestDto.setName("Longer"); requestDto.setHobby("ball"); String json = JacksonUtil.beanToJson(requestDto);

    //appIdString appId = ""; //rsa公鑰mongodbregexString publicKey = ""; //rsa私鑰String privateKey = ""

    ; HttpClientUtils.doPostJsonForSign(url, json, appId, publicKey, privateKey) }接收方controller

    @Slf4j@RestControllerpublicclassTestController{ @RequestMapping("test")public String test(RequestDto requestDto){ lomongodbregexg.info(

    "接收到的請求參數(shù)為:"+ JacksonUtil.beanToJson(requestDto)); return"a"; } }因為我們對參數(shù)進行了統(tǒng)一處理,所以我們的controller接收參數(shù)的對象是RequestDto對象,而不是JsonRequest對象

    原鏈接:https://www.jianshu.com/p/9061da5e25d1

    標簽列表

      湘阴县| 德格县| 衡南县| 揭西县| 贵南县| 郑州市| 安达市| 太保市| 洪江市| 库车县| 宣恩县| 呼图壁县| 蛟河市| 清水河县| 漳州市| 上栗县| 杭锦后旗| 阿拉善左旗| 蒙山县| 夹江县| 安图县| 松桃| 奉贤区| 舟曲县| 轮台县| 抚远县| 辰溪县| 兴山县| 瓮安县| 南和县| 类乌齐县| 定边县| 襄樊市| 正宁县| 都匀市| 赤水市| 石柱| 奉贤区| 澜沧| 凌源市| 浙江省|