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<String> aliases, Map<String,String> 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,value>:

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<Key,Value>

    public synchronized Set<Map.Entry<Object,Object>> entrySet()
    
    
  • 返回Provider中所有的Property条目中的Set<Key>

    public Set<Object> keySet() 
    
  • 返回Provider中所有的Property条目中的Collection<Key>

    public Collection<Object> 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<ServiceKey,Service> legacyMap;

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


X_Shadow
5 声望1 粉丝

小小菜鸟