Cipher

原文地址: Cipher

继承关系

  • java.lang.Object
    • ↳ javax.crypto.Cipher
      • 已知的的子类有NullCipher。

介绍

  这个类提供了关于密码的加密和解密的功能。它构成了Java加密扩展(JCE)框架的核心。
  为了创建一个Cipher对象,可以使用Cipher类中的getInstance(String transformation)方法来获取一个Cipher实例,其中的String transformation就是要创建的对象的请求信息,同时,还可以指定提供者的信息(可选)。
  transformation是一个String类型的参数,这个参数描述的是加密模式[, 填充字符,数据块大……],比如DES/CBC/PKCS5Padding
  transformation格式有以下几种:

  • 加密算法/加密模式/填充字符
  • 机密算法

      (在后面一种情况中,加密模式和填充字符采用的是默认值)。例如,以下是有效的transformation
      

Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");

  假如使用CFBOFB加密模式的话,block ciphers可以用于加密小于密码(ciphers)大小的单元数据。当请求一个加密模式的时候,我们可以指定数据块的大小,比如 “DES/CFB8/NoPadding” 和 “DES/OFB32/PKCS5Padding” 中的“CFB8”和“OFB32”中的数字就是数据块的大小。如果没有指定数据块的大小的话,那么就会采用程序定义的默认值。因此,如果需要的话,我们可以指定数据块为8bit的模式,如:CFB8 或 OFB8。
  比如具有关联数据的身份加密验证模式(AEAD)
可以为机密数据和未加密的附加关联数据(AAD)提供真实性的保障。(Please see RFC 5116 for more information on AEAD and AEAD algorithms such as GCM/CCM.) 在计算标记的真实性的时候可以使用那些可信的附加关联数据(AAD)数据。(在Mac中也类似。注:Mac指的是提供“信息认证码”的一个Java类。)此标记在加密期间被追加到密文文本中,并在解密中得到验证。
  例如GCM/CCM等的AEAD加密模式在开始进行密文的真实性计算之前,就会执行所有的AAD真实性计算。为了避免在内部缓冲加密文本,所有的AAD数据在处理之前(使用update和doFinal方法)传给“GCM/CC”的实现类(使用updateAAD方法)。
  请注意:GCM加密模式对于IVs(initialization vector)这种给定密钥加密的方式具有唯一性要求。当IVs被重复用于GCM加密的时候,很容易收到伪造攻击。因此,在GCM加密模式之前,调用者需要重新初始化Cipher对象来让GCM获得不同的IVs参数。

GCMParameterSpec s = ...;
cipher.init(..., s);

// If the GCM parameters were generated by the provider, it can
// be retrieved by:
// 
// 如果GCM参数是由提供程序生成的,那么它可以通过
// cipher.getparameters().getParameterSpec(gcmparameterspec.class)来恢复。
cipher.getParameters().getParameterSpec(GCMParameterSpec.class);

cipher.updateAAD(...);  // AAD
cipher.update(...);     // Multi-part update
cipher.doFinal(...);    // conclusion of operation

// Use a different IV value for every encryption
// 在每次加密中都使用不同的IV
byte[] newIv = ...;
s = new GCMParameterSpec(s.getTLen(), newIv);
cipher.init(..., s);
...

Cipher 加密参数

原版请点击:->直达

这里写图片描述
  这些转换是在Java密码体系结构标准算法名称文档的密码部分中描述的。
  可以查看:

概要

常量

类型常量说明
intDECRYPT_MODE用于初始化cipher的解密模式的常量。
常量值为2。
intENCRYPT_MODE用于初始化cipher的加密模式的常量。
常量值为1。
intPRIVATE_KEY用于表示将要解开的私钥变量。
常量值为2。
intPUBLIC_KEY用于表示将要解开的公钥变量。
常量值为1。
intSECRET_KEY用于表示将要解开的秘钥变量.
常量值为3。
intUNWRAP_MODE用于初始化cipher为未解密的模式。
常量值为4。
intWRAP_MODE用于初始化cipher为加密的模式。
常量值为3。

保护构造器

  创建一个Cipher实例:

Cipher(CipherSpi cipherSpi, Provider provider, String transformation)
参数名称说明
cipherSpiCipherSpi: the delegate代理
providerProvider: the provider提供者
transformationString: the transformation转换信息

公有方法

类型方法名说明
final intdoFinal(byte[] input, int inputOffset, int inputLen, byte[] output)单部分加(解)密数据操作,或者结束一个多部分的操作。
注意:如果抛出异常,那么这个Cipher对象就需要重置才可以重新使用。
注意:这个方法应该是复制安全的,这意味着输入和输出缓冲区可以引用相同的字节数组,而没有未处理的输入数据。
final intdoFinal(byte[] output, int outputOffset)结束多部分的加(解)密操作(具体取决于Cipher的初始化方法)。
注意:如果抛出异常,那么这个Cipher对象就需要重置才可以重新使用。
final byte[]doFinal()结束多部分的加(解)密操作(具体取决于Cipher的初始化方法)。
注意:如果抛出异常,那么这个Cipher对象就需要重置才可以重新使用。
final byte[]doFinal(byte[] input)单部分加(解)密数据操作,或者结束一个多部分的操作。
final intdoFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)单部分加(解)密数据操作,或者结束一个多部分的操作。
注意:如果抛出异常,那么这个Cipher对象就需要重置才可以重新使用。
注意:这个方法应该是复制安全的,这意味着输入和输出缓冲区可以引用相同的字节数组,而没有未处理的输入数据。
final intdoFinal(ByteBuffer input, ByteBuffer output)单部分加(解)密数据操作,或者结束一个多部分的操作。
注意:如果抛出异常,那么这个Cipher对象就需要重置才可以重新使用。
注意:这个方法应该是复制安全的,这意味着输入和输出缓冲区可以引用相同的字节数组,而没有未处理的输入数据。
final byte[]doFinal(byte[] input, int inputOffset, int inputLen)单部分加(解)密数据操作,或者结束一个多部分的操作。
注意:如果抛出异常,那么这个Cipher对象就需要重置才可以重新使用。
final StringgetAlgorithm()返回Cipher对象的算法名称。
final intgetBlockSize()返回数据块的大小(单位是bytes)。
final ExemptionMechanismgetExemptionMechanism()返回该Cipher使用的豁免机制(ExemptionMechanism)。
final byte[]getIV()返回新缓冲区区中的初始化向量(initialization vector (IV))。
static final CiphergetInstance(String transformation)返回特定转换的Cipher对象。
请注意,可以通过Security.getProvider()方法检索已注册的提供者的列表。
static final CiphergetInstance(String transformation, String provider)返回特定转换的Cipher对象。
请注意,可以通过Security.getProvider()方法检索已注册的提供者的列表。
static final CiphergetInstance(String transformation, Provider provider)返回特定转换的Cipher对象。
static final intgetMaxAllowedKeyLength(String transformation)根据已安装的JCE权限策略文件返回指定转换内容的最大密钥长度。
static final AlgorithmParameterSpecgetMaxAllowedParameterSpec(String transformation)返回一个根据权限策略文件形成的包含最大密码参数值的算法参数参数对象。
final intgetOutputSize(int inputLen)根据给定的输入长度 inputLen(以字节为单位),返回保存下一个 update 或 doFinal 操作结果所需的输出缓冲区长度(以字节为单位)。
final AlgorithmParametersgetParameters()返回在Cipher中使用到的参数。
final ProvidergetProvider()返回Cipher对象中的provide。
final voidinit(int opmode, Key key, AlgorithmParameters params)使用密钥、 随机数和一系列的算法参数实例化Cipher。
final voidinit(int opmode, Certificate certificate, SecureRandom random)用公钥、给定的证书和随机数实例化Cipher。
final voidinit(int opmode, Key key, SecureRandom random)用密钥和随机数实例化Cipher。
final voidinit(int opmode, Key key, AlgorithmParameterSpec params)使用密钥和一系列的算法参数实例化Cipher。
final voidinit(int opmode, Key key)使用密钥实例化Cipher。
final voidinit(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random)使用密钥、 随机数和一系列的算法参数实例化Cipher。
final voidinit(int opmode, Certificate certificate)使用密钥和给定的证书实例化Cipher。
final voidinit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)使用密钥、一系列的算法参数和随机数实例化Cipher。
final Keyunwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType)解密一个之前加密过的密钥。
final byte[]update(byte[] input)继续多部分的加(解)密操作(取决于Cipher的初始化方式),以处理其他部分的数据。
final intupdate(byte[] input, int inputOffset, int inputLen, byte[] output)继续多部分的加(解)密操作(取决于Cipher的初始化方式), 以处理其他部分的数据。
final byte[]update(byte[] input, int inputOffset, int inputLen)继续多部分的加(解)密操作(取决于Cipher的初始化方式), 以处理其他部分的数据。
final intupdate(ByteBuffer input, ByteBuffer output)继续多部分的加(解)密操作(取决于Cipher的初始化方式), 以处理其他部分的数据。
final intupdate(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)继续多部分的加(解)密操作(取决于Cipher的初始化方式), 以处理其他部分的数据。
final voidupdateAAD(byte[] src, int offset, int len)使用所提供的缓冲区的一个子集, 继续一个多部分update附加数据认证(AAD)的数据的操作。
final voidupdateAAD(ByteBuffer src)继续一个多部分update附加数据认证(AAD)的数据的操作。
final voidupdateAAD(byte[] src)继续一个多部分update附加数据认证的数据的操作。
final byte[]wrap(Key key)加密一个密钥。

继承方法

  请见java.lang.Object

示例

  注意:下面的示例需要导入一个包文件sun.misc.BASE64Decoder.jar点击我下载,下载好之后,将其设置为library就可以了。

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import Decoder.BASE64Decoder;
import Decoder.BASE64Encoder;

/**
 * Created on 5/11/17.
 * AES加密解密函数
 */
public class AESUtil {
    /**
     * 密钥算法
     */
    private static final String ALGORITHM = "AES";
    /**
     * 加解密算法/工作模式/填充方式
     */
    private static final String ALGORITHM_STR = "AES/ECB/PKCS5Padding";

    /**
     * SecretKeySpec类是KeySpec接口的实现类,用于构建秘密密钥规范
     */
    private SecretKeySpec key;

    public AESUtil(String hexKey) {
        if (hexKey != null) {
            key = new SecretKeySpec(hexKey.getBytes(), ALGORITHM);
        }
    }

    /**
     * AES加密
     * @param data 加密数据
     * @return 加密的字符串
     * @throws Exception
     */
    public String encryptData(String data) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM_STR); // 创建密码器
        cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
        return new BASE64Encoder().encode(cipher.doFinal(data.getBytes()));
    }

    /**
     * AES解密
     * @param base64Data
     * @return 返回解密的字符串
     * @throws Exception
     */
    public String decryptData(String base64Data) throws Exception{
        Cipher cipher = Cipher.getInstance(ALGORITHM_STR);
        cipher.init(Cipher.DECRYPT_MODE, key);
        return new String(cipher.doFinal(new BASE64Decoder().decodeBuffer(base64Data)));
    }

    /**
     * hex字符串 转 byte数组
     * @param s 待转换的字符串
     * @return byte[]
     */
    private static byte[] hex2byte(String s) {
        if (s.length() % 2 == 0) {
            return hex2byte (s.getBytes(), 0, s.length() >> 1);
        } else {
            return hex2byte("0"+s);
        }
    }

    /**
     * byte数组 转 hex字符串
     * @param b 待转换的字节流
     * @param offset 偏移量
     * @param len 待转换的字节流长度
     * @return byte[]
     */
    private static byte[] hex2byte (byte[] b, int offset, int len) {
        byte[] d = new byte[len];
        for (int i=0; i<len*2; i++) {
            int shift = i%2 == 1 ? 0 : 4;
            d[i>>1] |= Character.digit((char) b[offset+i], 16) << shift;
        }
        return d;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值