国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

javax.crypto.Cipher 源碼學(xué)習(xí)筆記

余學(xué)文 / 1815人閱讀

摘要:源碼學(xué)習(xí)筆記該類是用來(lái)加密的引擎類,支持對(duì)稱和非對(duì)稱加密。函數(shù)創(chuàng)建對(duì)象操作其中方法是在中操作的方法,其他幾個(gè)都使用執(zhí)行。狀態(tài)變化內(nèi)部類內(nèi)部類是用來(lái)解析中傳入的字符串的。查詢時(shí),也會(huì)查詢別名是否等于。知其然知其所以然。

javax.crypto.Cipher 源碼學(xué)習(xí)筆記

該類是JCE用來(lái)加密的引擎類,支持對(duì)稱和非對(duì)稱加密。該類的介紹可以參考:[[譯]JCA參考指南(二):核心類和接口](https://xshandow.gitee.io/201...

最近看了下OpenJDK中的Cipher源碼,現(xiàn)在介紹一下Cipher的內(nèi)部實(shí)現(xiàn)。

1.Cipher函數(shù)

創(chuàng)建Cipher對(duì)象:getInstance()

操作:init()、update()、doFinal()

GCM|CCM:updateAAD()

其中:getInstance()方法是在Cipher中操作的方法,其他幾個(gè)都使用spi.engin**()執(zhí)行。

狀態(tài)變化:

2.內(nèi)部類Transform

內(nèi)部類Transform是用來(lái)解析getInstanse()中傳入的transform字符串的。

setModePadding(CipherSpi spi)中通過spi.engineSetMode(mode|pad)設(shè)置,反饋模式和補(bǔ)丁方案。

判斷Provider.service是否支持提供的mod和pad.

3.getInstanse()

getInstanse()傳入的轉(zhuǎn)換的格式如下:

“algorithm/mode/padding” or(標(biāo)準(zhǔn)名稱)

“algorithm”

只傳入transformation:

public static final Cipher getInstance(String transformation)
        throws NoSuchAlgorithmException, NoSuchPaddingException
{
    //獲取Transform列表,帶alg
    List transforms = getTransforms(transformation);
    List cipherServices = new ArrayList(transforms.size());
    
    for (Iterator t = transforms.iterator(); t.hasNext(); ) {
        Transform transform = (Transform)t.next();

        //transform = alg + sufix(/[mode] + /[padding])
        //有四種形式:mode和padding是可選的
        cipherServices.add(new ServiceId("Cipher", transform.transform));
    }
    //獲取支持Transform(alg+suffix)的List
    //所有的Provider全部遍歷一遍
    List services = GetInstance.getServices(cipherServices);
    // make sure there is at least one service from a signed provider
    // and that it can use the specified mode and padding
    Iterator t = services.iterator();
    Exception failure = null;
    while (t.hasNext()) {
        Service s = (Service)t.next();
        if (JceSecurity.canUseProvider(s.getProvider()) == false) {
            continue;
        }
        //返回 transforms.suffix和算法的后綴一樣的第一個(gè)Transform
        Transform tr = getTransform(s, transforms);
        if (tr == null) {
            // should never happen
            continue;
        }
        //是否支持
        int canuse = tr.supportsModePadding(s);
        if (canuse == S_NO) {
            // does not support mode or padding we need, ignore
            continue;
        }
        //找到第一個(gè)結(jié)束
        if (canuse == S_YES) {
            return new Cipher(null, s, t, transformation, transforms);
        } else { // S_MAYBE, try out if it works
            try {
                CipherSpi spi = (CipherSpi)s.newInstance(null);
                tr.setModePadding(spi);
                return new Cipher(spi, s, t, transformation, transforms);
            } catch (Exception e) {
                failure = e;
            }
        }
    }
    throw new NoSuchAlgorithmException
        ("Cannot find any provider supporting " + transformation, failure);
}

另一種同時(shí)傳入Provider:

 public static final Cipher getInstance(String transformation,Provider provider)
        throws NoSuchAlgorithmException, NoSuchPaddingException
{
    if (provider == null) {
        throw new IllegalArgumentException("Missing provider");
    }
    Exception failure = null;
    List transforms = getTransforms(transformation);
    boolean providerChecked = false;
    String paddingError = null;
    for (Iterator t = transforms.iterator(); t.hasNext();) {
        Transform tr = (Transform)t.next();
        //直接搜該provider是否支持
        Service s = provider.getService("Cipher", tr.transform);
        if (s == null) {
            continue;
        }
        if (providerChecked == false) {
            // for compatibility, first do the lookup and then verify
            // the provider. this makes the difference between a NSAE
            // and a SecurityException if the
            // provider does not support the algorithm.
            Exception ve = JceSecurity.getVerificationResult(provider);
            if (ve != null) {
                String msg = "JCE cannot authenticate the provider "
                    + provider.getName();
                throw new SecurityException(msg, ve);
            }
            providerChecked = true;
        }
        if (tr.supportsMode(s) == S_NO) {
            continue;
        }
        if (tr.supportsPadding(s) == S_NO) {
            paddingError = tr.pad;
            continue;
        }
        try {
            CipherSpi spi = (CipherSpi)s.newInstance(null);
            tr.setModePadding(spi);
            Cipher cipher = new Cipher(spi, transformation);
            cipher.provider = s.getProvider();
            cipher.initCryptoPermission();
            return cipher;
        } catch (Exception e) {
            failure = e;
        }
    }

    // throw NoSuchPaddingException if the problem is with padding
    if (failure instanceof NoSuchPaddingException) {
        throw (NoSuchPaddingException)failure;
    }
    if (paddingError != null) {
        throw new NoSuchPaddingException
            ("Padding not supported: " + paddingError);
    }
    throw new NoSuchAlgorithmException
            ("No such algorithm: " + transformation, failure);
}

第一個(gè)getInstance(),將transform轉(zhuǎn)換成內(nèi)部Transform,遍歷所有的Provider,查詢到第一個(gè)支持transform的Service,然后new Cipher().

第二種getInstance(),將transform轉(zhuǎn)換成內(nèi)部Transform,直接通過provider.getService("Cipher", tr.transform)查詢是否支持transform,然后new Cipher().

注意:

tr.transform是通過下面介紹的的函數(shù)獲得的。

查詢service時(shí),也會(huì)查詢別名是否等于tr.transform。

4.List getTransforms(String transformation)
/**
 * 獲取Transform的List列表
 */
private static List getTransforms(String transformation)
        throws NoSuchAlgorithmException {
    String[] parts = tokenizeTransformation(transformation);

    String alg = parts[0];
    String mode = parts[1];
    String pad = parts[2];
    if ((mode != null) && (mode.length() == 0)) {
        mode = null;
    }
    if ((pad != null) && (pad.length() == 0)) {
        pad = null;
    }

    //Transform 僅有alg
    if ((mode == null) && (pad == null)) {
        // DES
        Transform tr = new Transform(alg, "", null, null);
        return Collections.singletonList(tr);
    } else { 
        // Transform = alg/mode/padding 的格式
        // if ((mode != null) && (pad != null)) {
        // DES/CBC/PKCS5Padding
        List list = new ArrayList(4);
        list.add(new Transform(alg, "/" + mode + "/" + pad, null, null));
        list.add(new Transform(alg, "/" + mode, null, pad));
        list.add(new Transform(alg, "http://" + pad, mode, null));
        list.add(new Transform(alg, "", mode, pad));
        return list;
    }
}
如果transform的格式時(shí)“algorithm/mode/padding”,會(huì)輸出4中形式的Transform,查詢支持某種就會(huì)返回。
4.ini()
public final void init(int opmode, Key key, SecureRandom random)
        throws InvalidKeyException
{
    initialized = false;
    checkOpmode(opmode);

    if (spi != null) {
        checkCryptoPerm(spi, key);
        spi.engineInit(opmode, key, random);
    } else {
        try {
            chooseProvider(I_KEY, opmode, key, null, null, random);
        } catch (InvalidAlgorithmParameterException e) {
            // should never occur
            throw new InvalidKeyException(e);
        }
    }

    initialized = true;
    this.opmode = opmode;
}

如上代碼,執(zhí)行ini()、update()..等操作時(shí),其實(shí)是執(zhí)行spi.engin**()

如果使用的mod需要傳入IV,這使用,init(Mode,Key,IvParameterSpec)出入IV。

GCMParameterSpec的時(shí)候IV必須每次都不同。

Transform標(biāo)準(zhǔn)名稱

可以參考Java Cryptography Architecture Standard Algorithm Name Documentation for JDK 8

總結(jié)

看Cipher源碼的原因是因?yàn)椋诳碆C的時(shí)候看到支持的transform列表中支持的是RSA/OAEP的加密模式,但是JCE中要求的傳日格式是“algorithm/mode/padding” or(標(biāo)準(zhǔn)名稱)“algorithm”,因此就產(chǎn)生了以問。

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/RAW -> org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi$NoPadding

BC: Cipher.RSA/PKCS1 -> org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi$PKCS1v1_5Padding
  aliases: [RSA//PKCS1PADDING]

BC: Cipher.RSA/1 -> org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi$PKCS1v1_5Padding_PrivateOnly

BC: Cipher.RSA/2 -> org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi$PKCS1v1_5Padding_PublicOnly

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

BC: Cipher.RSA/ISO9796-1 -> org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi$ISO9796d1Padding
  aliases: [RSA//ISO9796-1PADDING]

可以看出RSA/OAEP的別名正事RSA//OAEPPADING,所以也能夠查到RSA//OAEPPADING對(duì)應(yīng)的正是service中的RSA/OAEP。

知其然知其所以然。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/76821.html

相關(guān)文章

  • 慕課網(wǎng)_《Java實(shí)現(xiàn)對(duì)稱加密》學(xué)習(xí)總結(jié)

    時(shí)間:2017年4月11日星期二說明:本文部分內(nèi)容均來(lái)自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)示例源碼:https://github.com/zccodere/s...個(gè)人學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:對(duì)稱加密算法DES 1-1 JAVA對(duì)稱加密算法DES 加密密鑰=解密密鑰 對(duì)稱加密算法 初等 DES --3D...

    tomlingtm 評(píng)論0 收藏0
  • 慕課網(wǎng)_《Java實(shí)現(xiàn)非對(duì)稱加密》學(xué)習(xí)總結(jié)

    摘要:時(shí)間年月日星期三說明本文部分內(nèi)容均來(lái)自慕課網(wǎng)。秘密密鑰,生成一個(gè)分組的秘密密鑰。 時(shí)間:2017年4月12日星期三說明:本文部分內(nèi)容均來(lái)自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)示例源碼:https://github.com/zccodere/s...個(gè)人學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:概述 1-1 概述 非對(duì)稱...

    dailybird 評(píng)論0 收藏0
  • Java加密算法筆記--DES算法實(shí)現(xiàn)

    摘要:加密算法筆記算法實(shí)現(xiàn)在使用中發(fā)現(xiàn),經(jīng)過加密的字符串如果要進(jìn)行傳輸,需要使用進(jìn)行編碼,這樣能保證加密信息的完整性,確保將來(lái)解密成功。 Java加密算法筆記--DES算法實(shí)現(xiàn) 在使用中發(fā)現(xiàn),經(jīng)過加密的字符串如果要進(jìn)行傳輸,需要使用Base64進(jìn)行編碼,這樣能保證加密信息的完整性,確保將來(lái)解密成功。 import java.security.SecureRandom; import java...

    BlackFlagBin 評(píng)論0 收藏0
  • 原創(chuàng):微信小程序java實(shí)現(xiàn)AES解密并獲取unionId

    摘要:來(lái)自微信小程序聯(lián)盟如果大家使用小程序的同時(shí)還在使用公眾號(hào)的話,可能會(huì)用到這種功能,由于公司業(yè)務(wù)需要,我們需要使用,具體使用方法,請(qǐng)參考微信開放平臺(tái)的說明,但是在微信小程序的文檔中只給出了部分語(yǔ)言實(shí)現(xiàn)的源碼,竟然沒有的,小程序的開發(fā)人員是有多 來(lái)自:微信小程序聯(lián)盟 如果大家使用小程序的同時(shí)還在使用公眾號(hào)的話,可能會(huì)用到unionId這種功能,由于公司業(yè)務(wù)需要,我們需要使用unionId,...

    jackzou 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<