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的例項