为了账号安全,请及时绑定邮箱和手机立即绑定

Android的加密缓存(上)--JCA基础

标签:
Android

在Java的知识体系中,Java平台安全是很重要的一部分。作为Android开发者,其实这部分知识对我们来说既陌生又熟悉。说熟悉,Android中Apk打包离不开的jks签名文件,Android 6.0提供的指纹识别接口的调用(Demo), 都是建立在Android平台安全的体系上。而Android平台安全又是建立在Java平台安全的这个坚实的基础上。说陌生,对于Java密码学架构(Java Cryptography Architecture 简称JCA)的还挺陌生,该系列文章分为上下两部分,这一篇主要聊聊JCA的基础知识,可能有些枯燥,在下篇,我会结合具体代码,完成一次简单的字符串缓存加密和解密。

JCA的基本介绍

先看来自《Java Cryptography Architecture
(JCA) Reference Guide
》的一段背景介绍:

Java平台重视安全性,包括语言安全性,密码学,公钥基础设施,身份验证,安全通行和访问控制。
JCA是JDk平台上非常重要的部分,通过包含一个 “provider”架构,设计了一套API为包括 数字签名、消息摘要、证书和证书验证、加密(对称和非对称,分组和流式密码)、秘钥生成和管理、安全随机码生成等功能服务。

可以看出,JCA是Java平台安全的基础,其它相关的还有Java密码学拓展(Java Cryptography Extension 简称JCE)、Java Secure Socket Extension (JSSE) 、Java Generic Security Services (JGSS)。


JCA的设计原则

JCA在设计之初就遵循一些基本原则,也就是

·         实现的独立性和互操作性

·         算法的独立性和可扩展性

应用无需实现具体的安全算法,或者说应用请求来自Java平台的安全服务。这些安全服务在“providers”(下面会介绍)中实现,这些providers可以互相协作,与应用之间没有必然的绑定限制。Java平台提供了现成的实现算法的providers,应用也可以通过自定义providers来实现特殊的算法。

JCA的架构

Cryptographic Service Providers CSP 密码服务提供者

刚才在设计原则那部分,反复提到了“providers”,那providers到底是个什么东西呢? JCA文档是这么介绍的:

a package or set of packages that supply a concrete implementation of a subset of the JDK Security API cryptography features
一个包或包结合,提供JDK安全API密码特性的具体实现

这么看还是很抽象,首先要了解java.security.Provider,这个抽象类是所有安全提供者的基础类。每一个CSP,也就是我们的密码服务提供者,都包含java.security.Provider类的一个实例,这个实例包含了“providers”的名称和所有实现的安全服务/算法的列表,当我们需要某种算法时,JCA框架就会去查询这个“providers”数据库,找到匹配的实例并创建它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public abstract class Provider extends Properties {
    private String name;
    private String info;
    private double version;
    private transient Set<Map.Entry<Object,Object>> entrySet = null;
    private transient int entrySetCallCount = 0;
    private transient boolean initialized;
    ...
}

引用下JCA文档中的这张图:


配合这张图就很清晰了,我们开发者处于应用层,JCA框架层对应用层只提供接口,具体的实现逻辑被封装起来。

1
2
//我们仅需通过具体的Engine class并提供需要的算法名称“MD5”,我们就可以获得一个provider实现的消息摘要实例
MessageDigest md = MessageDigest.getInstance("MD5");

Key Management 秘钥的管理

KeyStore是一个数据库,它可以被用于管理秘钥和证书的仓库。秘钥可用于应用的的数据验证,加密或签名。Sun Microsystems提供了默认的KeyStore实现。它将秘钥实现为一个文件,使用专有的秘钥类型(格式)叫“jks”.其他的秘钥格式如”jceks”(一种比jks加密强度更大的秘钥库格式)、”pkcs12”等。Android开发者应该很熟悉jks,打包生成apk的时候,我们就会用到jkd格式的秘钥。

例如,Android系统提供了默认的KeyStore,可以通过名称“AndroidKeyStore”来获取

1
2
KeyStore mKeyStore = KeyStore.getInstance("AndroidKeyStore");

Engine Classes and Algorithms 引擎类和算法

例如上文MessageDigest就是一类引擎类,1.4会介绍一些常用的引擎类,这里就不多做介绍了。

JCA的核心类和接口

看到这,想必大家对Providers,KeyStore,引擎类, 算法这些概念有了一些基础的认知。先放松一下,看一下gakki的笑容,放松一下。


骚年,我们继续。从API这个角度入手,了解一下JCA框架有哪些基础的类。了解之后,才方便我们后面的实战部分。

JCA的类大致可以分为以下几种:

·         Provider and Security 类

·         各种Engine类,如SecureRandom, MessageDigest, Signature, Cipher, Mac, KeyFactory, SecretKeyFactory, KeyPairGenerator, KeyGenerator, KeyAgreement, AlgorithmParameters, AlgorithmParameterGenerator , KeyStore, and CertificateFactory

·         Key 接口和类

·         算法参数规格接口和类(the Algorithm Parameter Specification Interfaces and Classes)
秘钥规格接口和类(the Key Specification Interfaces and Classes)

·         多种支持和便利接口和类

Key

首先了解一下秘钥,对应的定义是java.security.Key,是所有opaque keys的顶层接口,所谓opaque keys,也就是无法直接访问到构成key的材料,也就是说opaque keys给予了访问限制。只能通过getAlgorithm()、getFormat()、getEncoded()这些方法来获取到秘钥指定的信息。

1
2
3
4
5
6
7
8
9
10
public interface Key extends java.io.Serializable {
    static final long serialVersionUID = 6603384152749567654L;
    public String getAlgorithm();
    public String getFormat();
    public byte[] getEncoded();
}

KeyStore

用于创建和管理秘钥库, KeyStore是秘钥的数据库。秘钥库中的私有秘钥有与之相关的证书链,用于验证相关联的公有密钥。秘钥库也包含来自受信任实体的证书。上文有介绍,这里就不多说了。

KeyGenerator

通过使用特殊算法来生成秘钥,如果希望生成非对称秘钥,请使用KeyPairGenerator

初始化:有两种初始化方式:

·         算法无关

1
2
3
4
5
public void init(SecureRandom random);
public void init(int keysize);
public void init(int keysize, SecureRandom random);

·         算法相关

1
2
3
public void init(AlgorithmParameterSpec params);
public void init(AlgorithmParameterSpec params, SecureRandom random);

生成秘钥

1
public SecretKey generateKey();

·         AlgorithmParameterSpec

算法参数,看源码可知只是个接口,具体的实现如KeyGenParameterSpec

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package java.security.spec;
/**
* A (transparent) specification of cryptographic parameters.
*
* <P> This interface contains no methods or constants. Its only purpose
* is to group (and provide type safety for) all parameter specifications.
* All parameter specifications must implement this interface.
*
* @author Jan Luehe
*
*
* @see java.security.AlgorithmParameters
* @see DSAParameterSpec
*
* @since 1.2
*/
public interface AlgorithmParameterSpec { }

KeyGenParameterSpec

参数很多,显然也是通过构建者模式进行的初始化,构建者AlgorithmParameterSpec.Builder,重要的参数有
秘钥别名,秘钥目的,block modes、EncryptionPadding等

PurposeEnum

秘钥目的:加密、解密、签名、验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public @interface PurposeEnum {}
/**
 * Purpose of key: encryption.
 */
public static final int PURPOSE_ENCRYPT = 1 << 0;
/**
 * Purpose of key: decryption.
 */
public static final int PURPOSE_DECRYPT = 1 << 1;
/**
 * Purpose of key: signing or generating a Message Authentication Code (MAC).
 */
public static final int PURPOSE_SIGN = 1 << 2;
/**
 * Purpose of key: signature or Message Authentication Code (MAC) verification.
 */
public static final int PURPOSE_VERIFY = 1 << 3;

下面介绍几个Engine class

Cipher

用于数据的加密和解密,通过秘钥初始化。有几种不同的算法:如 对称加密协议 symmetric bulk encryption(AES, DES, DESede, Blowfish, IDEA),流式加密 stream encryption(RC4等), 非对称加密 asymmetric encryption(RSA等), 密码基础的加密 password-based encryption(PBE)

signature

提供用于密码数字签名算法(如DSA或RSAwithMD5)的功能

MessageDigest

提供密码信息摘要(如SHA-1或MD5)的功能,接受任意直接长度的输入(byte[]格式),生成
固定长度的输出(称为digest或hash)

Mac

Message Authentication Code的缩写,与MessageDigest类似, 用于检测信息的完整性以及在不可靠媒介上存储(包含一个secret key,持有正确key的人能够验证已接收的信息)

 原文链接:http://www.apkbus.com/blog-705730-62532.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消