<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          設(shè)計(jì)一個(gè)安全對(duì)外的API接口,需要考慮哪些方面?

          共 8887字,需瀏覽 18分鐘

           ·

          2021-12-31 18:32

          來(lái)源:blog.csdn.net/zhou920786312/article/

          details/95536556

          如何保證外網(wǎng)開(kāi)放接口的安全性。

          • 使用加簽名方式,防止數(shù)據(jù)篡改
          • 信息加密與密鑰管理
          • 搭建OAuth2.0認(rèn)證授權(quán)
          • 使用令牌方式
          • 搭建網(wǎng)關(guān)實(shí)現(xiàn)黑名單和白名單

          一、令牌方式搭建搭建API開(kāi)放平臺(tái)

          方案設(shè)計(jì):

          1.第三方機(jī)構(gòu)申請(qǐng)一個(gè)appId,通過(guò)appId去獲取accessToken,每次請(qǐng)求獲取accessToken都要把老的accessToken刪掉

          2.第三方機(jī)構(gòu)請(qǐng)求數(shù)據(jù)需要加上accessToken參數(shù),每次業(yè)務(wù)處理中心執(zhí)行業(yè)務(wù)前,先去dba持久層查看accessToken是否存在(可以把a(bǔ)ccessToken放到redis中,這樣有個(gè)過(guò)期時(shí)間的效果),存在就說(shuō)明這個(gè)機(jī)構(gòu)是合法,無(wú)需要登錄就可以請(qǐng)求業(yè)務(wù)數(shù)據(jù)。不存在說(shuō)明這個(gè)機(jī)構(gòu)是非法的,不返回業(yè)務(wù)數(shù)據(jù)。

          3.好處:無(wú)狀態(tài)設(shè)計(jì),每次請(qǐng)求保證都是在我們持久層保存的機(jī)構(gòu)的請(qǐng)求,如果有人盜用我們accessToken,可以重新申請(qǐng)一個(gè)新的taken.

          二、基于OAuth2.0協(xié)議方式

          原理

          第三方授權(quán),原理和1的令牌方式一樣

          1.假設(shè)我是服務(wù)提供者A,我有開(kāi)發(fā)接口,外部機(jī)構(gòu)B請(qǐng)求A的接口必須申請(qǐng)自己的appid(B機(jī)構(gòu)id)

          2.當(dāng)B要調(diào)用A接口查某個(gè)用戶信息的時(shí)候,需要對(duì)應(yīng)用戶授權(quán),告訴A,我愿同意把我的信息告訴B,A生產(chǎn)一個(gè)授權(quán)token給B。

          3.B使用token獲取某個(gè)用戶的信息。

          聯(lián)合微信登錄總體處理流程

          1. 用戶同意授權(quán),獲取code
          2. 通過(guò)code換取網(wǎng)頁(yè)授權(quán)access_token
          3. 通過(guò)access_token獲取用戶openId
          4. 通過(guò)openId獲取用戶信息

          三、信息加密與密鑰管理

          • 單向散列加密
          • 對(duì)稱加密
          • 非對(duì)稱加密
          • 安全密鑰管理

          1.單向散列加密

          散列是信息的提煉,通常其長(zhǎng)度要比信息小得多,且為一個(gè)固定長(zhǎng)度。加密性強(qiáng)的散列一定是不可逆的,這就意味著通過(guò)散列結(jié)果,無(wú)法推出任何部分的原始信息。任何輸入信息的變化,哪怕僅一位,都將導(dǎo)致散列結(jié)果的明顯變化,這稱之為雪崩效應(yīng)。

          散列還應(yīng)該是防沖突的,即找不出具有相同散列結(jié)果的兩條信息。具有這些特性的散列結(jié)果就可以用于驗(yàn)證信息是否被修改。

          單向散列函數(shù)一般用于產(chǎn)生消息摘要,密鑰加密等,常見(jiàn)的有:

          • MD5(Message Digest Algorithm 5):是RSA數(shù)據(jù)安全公司開(kāi)發(fā)的一種單向散列算法,非可逆,相同的明文產(chǎn)生相同的密文。
          • SHA(Secure Hash Algorithm):可以對(duì)任意長(zhǎng)度的數(shù)據(jù)運(yùn)算生成一個(gè)160位的數(shù)值;

          SHA-1與MD5的比較

          因?yàn)槎呔蒑D4導(dǎo)出,SHA-1和MD5彼此很相似。相應(yīng)的,他們的強(qiáng)度和其他特性也是相似,但還有以下幾點(diǎn)不同:

          • 對(duì)強(qiáng)行供給的安全性:最顯著和最重要的區(qū)別是SHA-1摘要比MD5摘要長(zhǎng)32 位。使用強(qiáng)行技術(shù),產(chǎn)生任何一個(gè)報(bào)文使其摘要等于給定報(bào)摘要的難度對(duì)MD5是2128數(shù)量級(jí)的操作,而對(duì)SHA-1則是2160數(shù)量級(jí)的操作。這樣,SHA-1對(duì)強(qiáng)行攻擊有更大的強(qiáng)度。
          • 對(duì)密碼分析的安全性:由于MD5的設(shè)計(jì),易受密碼分析的攻擊,SHA-1顯得不易受這樣的攻擊。
          • 速度:在相同的硬件上,SHA-1的運(yùn)行速度比MD5慢。

          1、特征:雪崩效應(yīng)、定長(zhǎng)輸出和不可逆。

          2、作用是:確保數(shù)據(jù)的完整性。

          3、加密算法:md5(標(biāo)準(zhǔn)密鑰長(zhǎng)度128位)、sha1(標(biāo)準(zhǔn)密鑰長(zhǎng)度160位)、md4、CRC-32

          4、加密工具:md5sum、sha1sum、openssl dgst。

          5、計(jì)算某個(gè)文件的hash值,例如:md5sum/shalsum FileName,openssl dgst –md5/-sha

          2.對(duì)稱加密

          秘鑰:加密解密使用同一個(gè)密鑰、數(shù)據(jù)的機(jī)密性雙向保證、加密效率高、適合加密于大數(shù)據(jù)大文件、加密強(qiáng)度不高(相對(duì)于非對(duì)稱加密)

          對(duì)稱加密優(yōu)缺點(diǎn)

          • 優(yōu)點(diǎn):與公鑰加密相比運(yùn)算速度快。
          • 缺點(diǎn):不能作為身份驗(yàn)證,密鑰發(fā)放困難

          DES是一種對(duì)稱加密算法,加密和解密過(guò)程中,密鑰長(zhǎng)度都必須是8的倍數(shù)

          ?
          public?class?DES?{
          ?public?DES()?{
          ?}
          ?
          ?//?測(cè)試
          ?public?static?void?main(String?args[])?throws?Exception?{
          ??//?待加密內(nèi)容
          ??String?str?=?"123456";
          ??//?密碼,長(zhǎng)度要是8的倍數(shù)?密鑰隨意定
          ??String?password?=?"12345678";
          ??byte[]?encrypt?=?encrypt(str.getBytes(),?password);
          ??System.out.println("加密前:"?+str);
          ??System.out.println("加密后:"?+?new?String(encrypt));
          ??//?解密
          ??byte[]?decrypt?=?decrypt(encrypt,?password);
          ??System.out.println("解密后:"?+?new?String(decrypt));
          ?}
          ?
          ?/**
          ??*?加密
          ??*?
          ??*?@param?datasource
          ??*????????????byte[]
          ??*?@param?password
          ??*????????????String
          ??*?@return?byte[]
          ??*/

          ?public?static?byte[]?encrypt(byte[]?datasource,?String?password)?{
          ??try?{
          ???SecureRandom?random?=?new?SecureRandom();
          ???DESKeySpec?desKey?=?new?DESKeySpec(password.getBytes());
          ???//?創(chuàng)建一個(gè)密匙工廠,然后用它把DESKeySpec轉(zhuǎn)換成
          ???SecretKeyFactory?keyFactory?=?SecretKeyFactory.getInstance("DES");
          ???SecretKey?securekey?=?keyFactory.generateSecret(desKey);
          ???//?Cipher對(duì)象實(shí)際完成加密操作
          ???Cipher?cipher?=?Cipher.getInstance("DES");
          ???//?用密匙初始化Cipher對(duì)象,ENCRYPT_MODE用于將?Cipher?初始化為加密模式的常量
          ???cipher.init(Cipher.ENCRYPT_MODE,?securekey,?random);
          ???//?現(xiàn)在,獲取數(shù)據(jù)并加密
          ???//?正式執(zhí)行加密操作
          ???return?cipher.doFinal(datasource);?//?按單部分操作加密或解密數(shù)據(jù),或者結(jié)束一個(gè)多部分操作
          ??}?catch?(Throwable?e)?{
          ???e.printStackTrace();
          ??}
          ??return?null;
          ?}
          ?
          ?/**
          ??*?解密
          ??*?
          ??*?@param?src
          ??*????????????byte[]
          ??*?@param?password
          ??*????????????String
          ??*?@return?byte[]
          ??*?@throws?Exception
          ??*/

          ?public?static?byte[]?decrypt(byte[]?src,?String?password)?throws?Exception?{
          ??//?DES算法要求有一個(gè)可信任的隨機(jī)數(shù)源
          ??SecureRandom?random?=?new?SecureRandom();
          ??//?創(chuàng)建一個(gè)DESKeySpec對(duì)象
          ??DESKeySpec?desKey?=?new?DESKeySpec(password.getBytes());
          ??//?創(chuàng)建一個(gè)密匙工廠
          ??SecretKeyFactory?keyFactory?=?SecretKeyFactory.getInstance("DES");//?返回實(shí)現(xiàn)指定轉(zhuǎn)換的
          ???????????????????//?Cipher
          ???????????????????//?對(duì)象
          ??//?將DESKeySpec對(duì)象轉(zhuǎn)換成SecretKey對(duì)象
          ??SecretKey?securekey?=?keyFactory.generateSecret(desKey);
          ??//?Cipher對(duì)象實(shí)際完成解密操作
          ??Cipher?cipher?=?Cipher.getInstance("DES");
          ??//?用密匙初始化Cipher對(duì)象
          ??cipher.init(Cipher.DECRYPT_MODE,?securekey,?random);
          ??//?真正開(kāi)始解密操作
          ??return?cipher.doFinal(src);
          ?}
          }
          ?
          輸出
          ?
          加密前:123456
          加密后:>p.72|
          解密后:123456

          3.非對(duì)稱加密

          非對(duì)稱加密算法需要兩個(gè)密鑰:公開(kāi)密鑰(publickey:簡(jiǎn)稱公鑰)和私有密鑰(privatekey:簡(jiǎn)稱私鑰)。

          公鑰與私鑰是一對(duì)

          • 公鑰對(duì)數(shù)據(jù)進(jìn)行加密,只有用對(duì)應(yīng)的私鑰才能解密
          • 私鑰對(duì)數(shù)據(jù)進(jìn)行加密,只有用對(duì)應(yīng)的公鑰才能解密

          過(guò)程:

          • 甲方生成一對(duì)密鑰,并將公鑰公開(kāi),乙方使用該甲方的公鑰對(duì)機(jī)密信息進(jìn)行加密后再發(fā)送給甲方;
          • 甲方用自己私鑰對(duì)加密后的信息進(jìn)行解密。
          • 甲方想要回復(fù)乙方時(shí),使用乙方的公鑰對(duì)數(shù)據(jù)進(jìn)行加密
          • 乙方使用自己的私鑰來(lái)進(jìn)行解密。
          • 甲方只能用其私鑰解密由其公鑰加密后的任何信息。

          特點(diǎn):

          • 算法強(qiáng)度復(fù)雜
          • 保密性比較好
          • 加密解密速度沒(méi)有對(duì)稱加密解密的速度快。
          • 對(duì)稱密碼體制中只有一種密鑰,并且是非公開(kāi)的,如果要解密就得讓對(duì)方知道密鑰。所以保證其安全性就是保證密鑰的安全,而非對(duì)稱密鑰體制有兩種密鑰,其中一個(gè)是公開(kāi)的,這樣就可以不需要像對(duì)稱密碼那樣傳輸對(duì)方的密鑰了。這樣安全性就大了很多
          • 適用于:金融,支付領(lǐng)域

          RSA加密是一種非對(duì)稱加密

          import?javax.crypto.Cipher;
          import?java.security.*;
          import?java.security.interfaces.RSAPrivateKey;
          import?java.security.interfaces.RSAPublicKey;
          import?java.security.spec.PKCS8EncodedKeySpec;
          import?java.security.spec.X509EncodedKeySpec;
          import?java.security.KeyFactory;
          import?java.security.KeyPair;
          import?java.security.KeyPairGenerator;
          import?java.security.PrivateKey;
          import?java.security.PublicKey;
          import?org.apache.commons.codec.binary.Base64;
          ?
          ?
          /**
          ?*?RSA加解密工具類
          ?*
          ?*?
          ?*/

          public?class?RSAUtil?{
          ?
          ?public?static?String?publicKey;?//?公鑰
          ?public?static?String?privateKey;?//?私鑰
          ?
          ?/**
          ??*?生成公鑰和私鑰
          ??*/

          ?public?static?void?generateKey()?{
          ??//?1.初始化秘鑰
          ??KeyPairGenerator?keyPairGenerator;
          ??try?{
          ???keyPairGenerator?=?KeyPairGenerator.getInstance("RSA");
          ???SecureRandom?sr?=?new?SecureRandom();?//?隨機(jī)數(shù)生成器
          ???keyPairGenerator.initialize(512,?sr);?//?設(shè)置512位長(zhǎng)的秘鑰
          ???KeyPair?keyPair?=?keyPairGenerator.generateKeyPair();?//?開(kāi)始創(chuàng)建
          ???RSAPublicKey?rsaPublicKey?=?(RSAPublicKey)?keyPair.getPublic();
          ???RSAPrivateKey?rsaPrivateKey?=?(RSAPrivateKey)?keyPair.getPrivate();
          ???//?進(jìn)行轉(zhuǎn)碼
          ???publicKey?=?Base64.encodeBase64String(rsaPublicKey.getEncoded());
          ???//?進(jìn)行轉(zhuǎn)碼
          ???privateKey?=?Base64.encodeBase64String(rsaPrivateKey.getEncoded());
          ??}?catch?(NoSuchAlgorithmException?e)?{
          ???//?TODO?Auto-generated?catch?block
          ???e.printStackTrace();
          ??}
          ?}
          ?
          ?/**
          ??*?私鑰匙加密或解密
          ??*?
          ??*?@param?content
          ??*?@param?privateKeyStr
          ??*?@return
          ??*/

          ?public?static?String?encryptByprivateKey(String?content,?String?privateKeyStr,?int?opmode)?{
          ??//?私鑰要用PKCS8進(jìn)行處理
          ??PKCS8EncodedKeySpec?pkcs8EncodedKeySpec?=?new?PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyStr));
          ??KeyFactory?keyFactory;
          ??PrivateKey?privateKey;
          ??Cipher?cipher;
          ??byte[]?result;
          ??String?text?=?null;
          ??try?{
          ???keyFactory?=?KeyFactory.getInstance("RSA");
          ???//?還原Key對(duì)象
          ???privateKey?=?keyFactory.generatePrivate(pkcs8EncodedKeySpec);
          ???cipher?=?Cipher.getInstance("RSA");
          ???cipher.init(opmode,?privateKey);
          ???if?(opmode?==?Cipher.ENCRYPT_MODE)?{?//?加密
          ????result?=?cipher.doFinal(content.getBytes());
          ????text?=?Base64.encodeBase64String(result);
          ???}?else?if?(opmode?==?Cipher.DECRYPT_MODE)?{?//?解密
          ????result?=?cipher.doFinal(Base64.decodeBase64(content));
          ????text?=?new?String(result,?"UTF-8");
          ???}
          ?
          ??}?catch?(Exception?e)?{
          ???//?TODO?Auto-generated?catch?block
          ???e.printStackTrace();
          ??}
          ??return?text;
          ?}
          ?
          ?/**
          ??*?公鑰匙加密或解密
          ??*?
          ??*?@param?content
          ??*?@param?privateKeyStr
          ??*?@return
          ??*/

          ?public?static?String?encryptByPublicKey(String?content,?String?publicKeyStr,?int?opmode)?{
          ??//?公鑰要用X509進(jìn)行處理
          ??X509EncodedKeySpec?x509EncodedKeySpec?=?new?X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr));
          ??KeyFactory?keyFactory;
          ??PublicKey?publicKey;
          ??Cipher?cipher;
          ??byte[]?result;
          ??String?text?=?null;
          ??try?{
          ???keyFactory?=?KeyFactory.getInstance("RSA");
          ???//?還原Key對(duì)象
          ???publicKey?=?keyFactory.generatePublic(x509EncodedKeySpec);
          ???cipher?=?Cipher.getInstance("RSA");
          ???cipher.init(opmode,?publicKey);
          ???if?(opmode?==?Cipher.ENCRYPT_MODE)?{?//?加密
          ????result?=?cipher.doFinal(content.getBytes());
          ????text?=?Base64.encodeBase64String(result);
          ???}?else?if?(opmode?==?Cipher.DECRYPT_MODE)?{?//?解密
          ????result?=?cipher.doFinal(Base64.decodeBase64(content));
          ????text?=?new?String(result,?"UTF-8");
          ???}
          ??}?catch?(Exception?e)?{
          ???//?TODO?Auto-generated?catch?block
          ???e.printStackTrace();
          ??}
          ??return?text;
          ?}
          ?
          ?//?測(cè)試方法
          ?public?static?void?main(String[]?args)?{
          ??/**
          ???*?注意:?私鑰加密必須公鑰解密?公鑰加密必須私鑰解密
          ???*??//?正常在開(kāi)發(fā)中的時(shí)候,后端開(kāi)發(fā)人員生成好密鑰對(duì),服務(wù)器端保存私鑰?客戶端保存公鑰
          ???*/

          ??System.out.println("-------------生成兩對(duì)秘鑰,分別發(fā)送方和接收方保管-------------");
          ??RSAUtil.generateKey();
          ??System.out.println("公鑰:"?+?RSAUtil.publicKey);
          ??System.out.println("私鑰:"?+?RSAUtil.privateKey);
          ?
          ??System.out.println("-------------私鑰加密公鑰解密-------------");
          ???String?textsr?=?"11111111";
          ???//?私鑰加密
          ???String?cipherText?=?RSAUtil.encryptByprivateKey(textsr,
          ???RSAUtil.privateKey,?Cipher.ENCRYPT_MODE);
          ???System.out.println("私鑰加密后:"?+?cipherText);
          ???//?公鑰解密
          ???String?text?=?RSAUtil.encryptByPublicKey(cipherText,
          ???RSAUtil.publicKey,?Cipher.DECRYPT_MODE);
          ???System.out.println("公鑰解密后:"?+?text);
          ?
          ??System.out.println("-------------公鑰加密私鑰解密-------------");
          ??//?公鑰加密
          ??String?textsr2?=?"222222";
          ?
          ??String?cipherText2?=?RSAUtil.encryptByPublicKey(textsr2,?RSAUtil.publicKey,?Cipher.ENCRYPT_MODE);
          ??System.out.println("公鑰加密后:"?+?cipherText2);
          ??//?私鑰解密
          ??String?text2?=?RSAUtil.encryptByprivateKey(cipherText2,?RSAUtil.privateKey,?Cipher.DECRYPT_MODE);
          ??System.out.print("私鑰解密后:"?+?text2?);
          ?}
          ?
          }

          四、使用加簽名方式,防止數(shù)據(jù)篡改

          客戶端:請(qǐng)求的數(shù)據(jù)分為2部分(業(yè)務(wù)參數(shù),簽名參數(shù)),簽名參數(shù)=md5(業(yè)務(wù)參數(shù))

          服務(wù)端:驗(yàn)證md5(業(yè)務(wù)參數(shù))是否與簽名參數(shù)相同

          程序汪資料鏈接

          程序汪接的7個(gè)私活都在這里,經(jīng)驗(yàn)整理

          Java項(xiàng)目分享 最新整理全集,找項(xiàng)目不累啦 06版

          堪稱神級(jí)的Spring Boot手冊(cè),從基礎(chǔ)入門到實(shí)戰(zhàn)進(jìn)階

          臥槽!字節(jié)跳動(dòng)《算法中文手冊(cè)》火了,完整版 PDF 開(kāi)放下載!

          臥槽!阿里大佬總結(jié)的《圖解Java》火了,完整版PDF開(kāi)放下載!

          字節(jié)跳動(dòng)總結(jié)的設(shè)計(jì)模式 PDF 火了,完整版開(kāi)放下載!


          歡迎添加程序汪個(gè)人微信 itwang005? 進(jìn)粉絲群或圍觀朋友圈

          瀏覽 71
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精彩无码视频 | 欧美一级视频网站 | 99精品久久久久久中文字幕 | 中文字幕+乱码+中文字幕明步 | 色老板最新地址 |