java和go中的密码学(10)-Provider和SPI原理

标签:密码学
发布时间:2018年11月19日 价值:20000.00 / 共识:29

本文部分片段参考官方文档:Java Cryptography Architecture (JCA) Reference Guide

由前文,大家初步了解到常见的加解密实现包:Sun系列和BC系列,其中前者不开源。

sun系列加解密包实现


图示如下:
Sunec.jar: 椭圆曲线相关算法:Sun Elliptic Curve provider (EC, ECDSA, ECDH)

Sunjce_provider.jar: 包含一系列的对称、非对称加解密算法具体实现:RSA, DES, Triple DES, AES, Blowfish, ARCFOUR, RC2, PBE, Diffie-Hellman, HMAC。可惜是闭源。不再截图演示。
Sunmscapi.jar: Microsoft Crypto API包(Sun’s Microsoft Crypto API provider),类中native方法调用微软操作系统加密api。目前主要是RSA算法相关实现

Sunpkcs11.jar: 基于PKCS#11公私钥证书规范的常见加解密算法实现

上面的包中同一个算法会有重复实现的,如RSACipher等。

BC.jar: 则不再截图演示。

Provider 的内部运作原理

由前文得知,系统启动时会自动加载一系列的Provider实现类如下:

之所以会出现那么多Provider的实现,是因为历史缘故。那么多Provider都可以从上文中的Sun*系列包中找到。

既然那么多Provider、同一个加解密算法那么多实现(每个服务商各自实现一遍),那么我们应用程序中该如何使用呢?如何指定用哪个服务商的加解密算法实现呢?下面例子说明:
(1)我们可以指定Provider:

  1. md = MessageDigest.getInstance("SHA-256", "ProviderC");// 使用ProviderC中包含的SHA-256算法实现。

如下图,通过ProviderC找到对应的ProviderC实例,从实例中找到这个服务商提供的SHA-256算法实现实例返回。

(2)我们可以不指定Provider:

  1. md = MessageDigest.getInstance("SHA-256");

这种情况,则是从一个个Provider实例中找,只要找到SHA-256算法实现实例就返回。

SPI 的原理

由前文,我们知道引擎类的使用。可是引擎类并没有对应的算法实现,ta仅仅是一个路由作用(或者说门面的作用)而已,帮我们路由到具体算法实现的类实例并返回。这个类,就是引擎类对应的spi类。
spi, 全称:Service Provider Interface 服务提供者接口,是真正实现了加解密算法逻辑的类。
其实在java的设计中,每个引擎类都对应着至少一个同名spi。Spi才是加解密算法的具体实现。
如Cipher —> CipherSpi(子类):

又如 MessageDigest —> MessageDigestSpi(子类):

那AES来说,Cipher.getInstance(“AES”)只是在帮你路由到某个Provider实例中包含的AESCipher类实例而已!
举例如下:

  1. import javax.crypto.*;
  2. Cipher c = Cipher.getInstance("AES");
  3. c.init(ENCRYPT_MODE, key);

  • 分享 收藏
0 条评论
  • 这篇文章暂无评论,赶紧评论一下吧~