资讯专栏INFORMATION COLUMN

java.security.Provider 源码学习笔记

quietin / 1508人阅读

摘要:内部类提供本服务的服务的类型算法名称本服务的实现类的名称别名列表空如果服务没有别名属性映射空如果实现没有属性以的算法为例输出的结果其中查看支持的密钥类型继承类函数前三种是类的全路径名称带有后三种中的方法返回中所有的条目返回中所有的条目中

java.security.Provider 内部类Service
/**
* Construct a new service.
*
* @param provider     提供本服务的Provider
* @param type         服务的类型
* @param algorithm     算法名称
* @param className     本服务的实现类的名称
* @param aliases     别名列表|空(如果服务没有别名)
* @param attributes 属性映射|空(如果实现没有属性)
*
* @throws NullPointerException if provider, type, algorithm, or
* className is null
*/
public Service(Provider provider, String type, String algorithm,
    String className, List aliases, Map attributes)

以BC的RSA算法为例toString()输出的结果

BC: Cipher.RSA -> org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi$NoPadding
  aliases: [RSA//RAW, RSA//NOPADDING]
  attributes: {SupportedKeyFormats=PKCS#8|X.509, SupportedKeyClasses=javax.crypto.interfaces.RSAPublicKey|javax.crypto.interfaces.RSAPrivateKey}

BC: Cipher.RSA/OAEP -> org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi$OAEPPadding
  aliases: [RSA//OAEPPADDING]

其中:

Service.className = org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi$NoPadding

Service.type = Cipher

Service.algorithm = RSA

查看支持的密钥类型:

public boolean supportsParameter(Object parameter)

attributes:SupportedKeyFormats=PKCS#8|X.509

继承Properties类

函数put

Key=

type.algorithm

type.oid

type.OID.oid

Alg.Alias.type.algorithm

Alg.Alias.type.oid

Alg.Alias.type.OID.oid

value = className

key = type.algorithm(前三种),value是spi类的全路径名称

key = 带有Alg.Alias..(后三种),value = type.algorithm中的algorithm.

方法

返回Provider中所有的property条目Set

public synchronized Set> entrySet()

返回Provider中所有的Property条目中的Set

public Set keySet() 

返回Provider中所有的Property条目中的Collection

public Collection values()

根据Type和algorithm获取Service

public synchronized Service getService(String type, String algorithm)

继承自Property的函数

添加
public synchronized Object put(Object key, Object value)
public synchronized void putAll(Map t)

删除
public synchronized Object remove(Object key)
public synchronized void clear()

获取
public Object get(Object key)
public String getProperty(String key)

type,algorithm到service的转换
provider.put(key,value)
name = key,value = value
private void parseLegacyPut(String name, String value) {
    if (name.toLowerCase(ENGLISH).startsWith(ALIAS_PREFIX_LOWER)) {
        // e.g. put("Alg.Alias.MessageDigest.SHA", "SHA-1");
        // aliasKey ~ MessageDigest.SHA
        String stdAlg = value;
        String aliasKey = name.substring(ALIAS_LENGTH);
        String[] typeAndAlg = getTypeAndAlgorithm(aliasKey);
        if (typeAndAlg == null) {
            return;
        }
        String type = getEngineName(typeAndAlg[0]);
        String aliasAlg = typeAndAlg[1].intern();
        ServiceKey key = new ServiceKey(type, stdAlg, true);
        Service s = legacyMap.get(key);
        if (s == null) {
            s = new Service(this);
            s.type = type;
            s.algorithm = stdAlg;
            legacyMap.put(key, s);
        }
        legacyMap.put(new ServiceKey(type, aliasAlg, true), s);
        s.addAlias(aliasAlg);
    } else {
        String[] typeAndAlg = getTypeAndAlgorithm(name);
        if (typeAndAlg == null) {
            return;
        }
        int i = typeAndAlg[1].indexOf(" ");
        if (i == -1) {
            // e.g. put("MessageDigest.SHA-1", "sun.security.provider.SHA");
            String type = getEngineName(typeAndAlg[0]);
            String stdAlg = typeAndAlg[1].intern();
            String className = value;
            ServiceKey key = new ServiceKey(type, stdAlg, true);
            Service s = legacyMap.get(key);
            if (s == null) {
                s = new Service(this);
                s.type = type;
                s.algorithm = stdAlg;
                legacyMap.put(key, s);
            }
            s.className = className;
        } else { // attribute
            // e.g. put("MessageDigest.SHA-1 ImplementedIn", "Software");
            String attributeValue = value;
            String type = getEngineName(typeAndAlg[0]);
            String attributeString = typeAndAlg[1];
            String stdAlg = attributeString.substring(0, i).intern();
            String attributeName = attributeString.substring(i + 1);
            // kill additional spaces
            while (attributeName.startsWith(" ")) {
                attributeName = attributeName.substring(1);
            }
            attributeName = attributeName.intern();
            ServiceKey key = new ServiceKey(type, stdAlg, true);
            Service s = legacyMap.get(key);
            if (s == null) {
                s = new Service(this);
                s.type = type;
                s.algorithm = stdAlg;
                legacyMap.put(key, s);
            }
            s.addAttribute(attributeName, attributeValue);
        }
    }
}

调用parseLegacyPut(),实际是将type,algorithm等转换成Map legacyMap;

引擎类在getInstance()的时候去调用Provider.getService(type,algorithm)方法,通过ServiceKey(type,algorithm)获取到Service.
然后在引擎类的getInstance()中调用service.newInstance()返回引擎类spi的实例

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/76920.html

相关文章

  • 【LNMPR源码学习笔记汇总

    摘要:此文用于汇总跟随陈雷老师及团队的视频,学习源码过程中的思考整理与心得体会,此文会不断更新视频传送门每日学习记录使用录像设备记录每天的学习源码学习源码学习内存管理笔记源码学习内存管理笔记源码学习内存管理笔记源码学习基本变量笔记 此文用于汇总跟随陈雷老师及团队的视频,学习源码过程中的思考、整理与心得体会,此文会不断更新 视频传送门:【每日学习记录】使用录像设备记录每天的学习 PHP7...

    Barrior 评论0 收藏0
  • Laravel学习笔记之Container源码解析

    摘要:实际上的绑定主要有三种方式且只是一种的,这些已经在学习笔记之实例化源码解析聊过,其实现方法并不复杂。从以上源码发现的反射是个很好用的技术,这里给出个,看下能干些啥打印结果太长了,就不粘贴了。 说明:本文主要学习Laravel中Container的源码,主要学习Container的绑定和解析过程,和解析过程中的依赖解决。分享自己的研究心得,希望对别人有所帮助。实际上Container的绑...

    huayeluoliuhen 评论0 收藏0
  • Java concurrent 源码学习笔记1 - 概览

    摘要:源码学习笔记基于包源码大致分为以下几组对包集合框架的扩展更好的支持多线程并发操作线程池相关锁基本数据类型的原子性封装 Java concurrent 源码学习笔记基于JDK1.8 concurrent包源码大致分为以下几组: 对util包集合框架的扩展(更好的支持多线程并发操作) 线程池相关 锁 基本数据类型的原子性封装 showImg(https://segmentfault.c...

    CocoaChina 评论0 收藏0

发表评论

0条评论

quietin

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<