天天看點

java+android+ios三端非對稱接口加密

算法:有rsa及aes算法

Java端處理方式:

入參處理方式

1、參數通過request.getParameter擷取的話,可以通過自己定義一個filter來進行處理。

定義兩個類,分别繼承HttpServletRequestWrapper及Filter,将該filter配置到web.xml裡面,在其他filter前面,以免影響程式擷取參數的調用

public class SafeTextRequestWrapper extends HttpServletRequestWrapper {

    public SafeTextRequestWrapper(HttpServletRequest req) {

        super(req);

    }

    @Override

    public Map<String, String[]> getParameterMap() {

        Map<String, String[]> paramMap = super.getParameterMap();

        for (String[] values : paramMap.values()) {

            for (int i = 0; i < values.length; i++) {

                values[i] = SensitiveUtil.filter(values[i]);

            }

        }

        return paramMap ;

    }

    @Override

public String getParameter(String name) {

//這裡就是對request請求擷取的參數進行解密

        return SensitiveUtil.filter(super.getParameter(name));

    }

}

public class SafeTextFilter implements Filter {

    @Override

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        SafeTextRequestWrapper safeTextRequestWrapper = new SafeTextRequestWrapper((HttpServletRequest) request);

        chain.doFilter(safeTextRequestWrapper, response);

    }

    @Override

    public void destroy() {

    }

}

2、參數如果是調用接口的入參,那麼可以通過aop的around注解的方式進行處理

@Around("webLog()")

public Object aroundMethod(ProceedingJoinPoint pjd) {

Object result = null;

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

Object[] args = pjd.getArgs(); // 擷取目标對象方法參數

if (args.length > 0) {

//對入參進行解密,這塊主要是針對方法裡面的參數處理的

for (int i = 0; i < args.length; i++) {

if (args[i] instanceof String) {

try {

args[i] = AES.decrypt(args[i].toString(), key);

} catch (Exception e) { // 使用異常機制來驗證 log.error("SystemLogs解密參數錯誤" + args[i], e);

}

}

}

}

try {

// 記錄方法開始執行時間

long startTime = System.currentTimeMillis();

result = pjd.proceed(args);

// 記錄方法結束執行時間,及寫入到資料庫

long E_time = System.currentTimeMillis() - startTime;

String methodName = pjd.getSignature().getDeclaringTypeName() + "." + pjd.getSignature().getName() + "()";

//将方法的執行時間記入到資料庫

logsService.saveSysLogs(request, E_time + "ms");

// 對結果進行加密處理

Map<String, String> map = new HashMap<String, String>();

map.put("result", AES.encrypt(JSON.toJSONString(result), key));

map.put("end","ok");

return map;

} catch (Throwable throwable) {

log.error(throwable.toString());

}

return result;

}

Java加解密方案到此為止

-----------------------------------------------------------------------

Ios加解密方案:

加密流程:

APP:代碼随機生成16位字元串的key,用這個key對加密内容進行AES加密

把随機生成的16位key用RSA公鑰加密

把加密的key 和 加密的内容兩個部分 傳到背景

背景Java:

收到兩個部分的東西,一個是加密的key,一個是加密的内容

用RSA私鑰解密key,得到key

用key解密用AES加密的内容,得到請求的資訊

操作流程:

通過OpenSSL生成私鑰和公鑰

根據生成的公鑰找到公鑰字元串

#define pubkey         @"-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwgsVWu7N9gpH4/V65WjiU+D0KkLE94uOmaChU/waE1LvOOOl4jzvbeXtFzILsbAaeZnT6xR/M7LEV3Kx8YyQk1/IhxR8D8jG64p6Y5gaQlji2QkG6qBrvXN8zhqb4qhEGsVmVAnEhJnICF2Z9pdfak/yE8IV4hOd7aXywNHkOT1PVVsUM8PMXdWa2tSJIGGleRhNilH2pI780enBJGOiLiZj4j6BZZhpfht8a7QV2Vxb6SiIthdOCeWeCmGXQvekmJNlbxDybA6kqH6qfL/Y/vk2xeRLxPYx6WQIDAQAB-----END PUBLIC KEY-----"

1、 首先随機生成16位字元串,作為AES加密的key

    NSString *key = [SecurityUtil randomlyGenerated16BitString];

2、 用AES的KEY 加密傳輸内容

NSString * encryptString = [SecurityUtil encryptAESData:paramstring withKey:key];

3、 用RSA加密 AES的key

NSString * encWithPubKey = [RSA  encryptString:key publicKey:pubkey];

4、 把加密的key 和 加密的内容發給背景伺服器

[dic setObject: encryptString forKey:@"parameters"];

[dic setObject:encWithPubKey forKey:@"key"];

Android加解密方案:

1、 加載公鑰

String public Key= "DvhHR9zS3n91VP9uG7Nv08S2uFipntadwdeILsbAaeZnT6xR/M7LEV3Kx8YyQk1/IhxR8D8jG64p6Y5gaQlji2QkG6qBrvXN8zhqb4qhEGsVmVAnEhJnICF2Z9pdfak/yE8IV4hOd7aXywNHkOT1PVVsUM8PMXdWa2tSJIGGleRhNilH2pI780enBJGOiLiZj4j6BZZhpfht8a7QV2Vxb6SiIthdOCeWeCmGXQvekmJNlbxDybA6kqH6qfL/Y/vk2xeRLxPYx6WQIDAQAB";

2、 生成一個16位随機字元串作為AES的key

strRand="" ;

for(int i=0;i<16;i++){

strRand += String.valueOf((int)(Math.random() * 10)) ;

}

3、 用AES 加密内容

String encryptContent = AESOperator.encrypt(content, strRand);

4、 用RSA公鑰對key加密

String key = RSAUtils.encryptData(strRand);

5、 用key對AES解密

String decrypt = AESOperator.decrypt(content, strRand);