JCA 实践记录——Cipher

Cipher类提供加密和解密的功能。

实例化

Cipher没有公开的构造方法,所以只能调用其静态方法getInstace进行实现化。这个方法有多个重载如下:

public static final Cipher getInstance(String algorithm) 
    throws NoSuchAlgorithmException, NoSuchPaddingException;


public static final Cipher getInstance(String algorithm, String provider ) 
    throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException;


public static final Cipher getInstance(String algorithm, Provider provider )
    throws NoSuchAlgorithmException, NoSuchPaddingException

我们通常使用的是public static final Cipher getInstance(String algorithm);此方法需要一个字符串作为参数,这个参数有以下两种形式:

  1. "算法":使用Provider给定的默认“模式”和“填充”。
  2. "算法/模式/填充"

注:使用 CFB 和 OFB 之类的模式,Cipher 块可以加密单元中小于该 Cipher 的实际块大小的数据。请求这样一个模式时,可以指定一次处理的位数(可选):将此数添加到模式名称中,正如 "DES/CFB8/NoPadding" 和 "DES/OFB32/PKCS5Padding" 转换所示。如果未指定该数,则将使用特定于提供者的默认值。(例如,SunJCE 提供者对 DES 使用默认的 64 位)。因此,通过使用如 CFB8 或 OFB8 的 8 位模式,Cipher 块可以被转换为面向字节的 Cipher 流。

需要了解的静态字段

public static final int ENCRYPT_MODE  //用于将 Cipher 初始化为加密模式的常量。

public static final int DECRYPT_MODE  //用于将 Cipher 初始化为解密模式的常量。
public static final int WRAP_MODE   //用于将 Cipher 初始化为密钥包装模式的常量。
public static final int UNWRAP_MODE  //用于将 Cipher 初始化为密钥解包模式的常量。
public static final int PUBLIC_KEY  //用于表示要解包的密钥为“公钥”的常量。
public static final int PRIVATE_KEY  //用于表示要解包的密钥为“私钥”的常量。
public static final int SECRET_KEY  //用于表示要解包的密钥为“秘密密钥”的常量。

初始化方法

// 仅使用密钥进行初始化
public final void init(int mode, Key key) 
    throws InvalidKeyException

// 用密钥和随机源初始化此 Cipher。
public final void init(int mode, Key key, SecureRandom random) 
    throws InvalidKeyException

//用密钥和一组算法参数初始化此 Cipher。
public final void init(int mode, Key key,
     AlgorithmParameterSpec paramSpcec) 
    throws InvalidKeyException, InvalidAlgorithmParameterException

// 用密钥、一组算法参数和随机源初始化此 Cipher。
public final void init(int mode, Key key,
     AlgorithmParameterSpec paramSpec, SecureRandom random)
     throws InvalidKeyException, InvalidAlgorithmParameterException

// 用密钥和一组算法参数初始化此 Cipher。
public final void init(int mode, Key key, AlgorithmParameters param) 
    throws InvalidKeyException, InvalidAlgorithmParameterException

// 用密钥、一组算法参数和随机源初始化此 Cipher。
public final void init(int mode, Key key, 
    AlgorithmParameters param, SecureRandom random) 
    throws InvalidKeyException, InvalidAlgorithmParameterException

// 用取自给定证书的公钥初始化此 Cipher。
public final void init(int mode, Certificate certificate) 
 throws InvalidKeyException

// 用取自给定证书的公钥和随机源初始化此 Cipher。
public final void init(int mode, Certificate certificate, 
    SecureRandom random) 
    throws InvalidKeyException

我们通常使用的是public final void init(int mode, Key key)。有四种mode可供选择,分别对应于Cipher中的四个常量如下:

  1. ENCRYPT_MODE 用于将 Cipher 初始化为加密模式。
  2. DECRYPT_MODE 用于将 Cipher 初始化为解密模式。
  3. WRAP_MODE 用于将 Cipher 初始化为密钥包装模式。
  4. UNWRAP_MODE 用于将 Cipher 初始化为密钥解包模式。

如果此 Cipher 需要任何无法从给定 key 派生的算法参数,则在为加密或密钥包装初始化时,底层 Cipher 实现应自己生成所需的参数(使用特定于提供者的默认值或随机值);在为解密或密钥解包初始化时,将引发 InvalidKeyException。可以用 getParameters 或 getIV 获取生成的参数(如果该参数为 IV)。

如果此 Cipher(包括其底层反馈或填充方案)需要随机字节(例如,用于参数生成),那么它将使用具有最高优先级的已安装提供者的 SecureRandom 实现作为随机源获取这些字节。(如果已安装的提供者都不提供 SecureRandom 实现,则将使用系统提供的随机源)。

update 和 doFinal 方法

update方法有多个重载如下:

public final byte[] update(byte[] input)

public final byte[] update(byte[] input, int offset, int len)

public final int update(byte[] input, int offset, int len, byte[] output) 
    throws ShortBufferException

public final int update(byte[] input, int inOffset, int len, byte[] output, int outOffset) 
    throws ShortBufferException

public final int update(ByteBuffer input, ByteBuffer output) 
    throws ShortBufferException

// doFinal 方法除下面这个无参方法外,还有五个与update参数一致的重载方法,
// 它们相当于使用同样的参数调用update后再调用无参doFinal
public final byte[] doFinal() 
    throws IllegalBlockSizeException, BadPaddingException

update方法有于在多部分加密或解密操作中处理其他未完成加密或解密的部分数据。doFinal则用于完成一次加密或解密操作,并将Cipher对象重置为上一次调用init方法时的状态。

wrap 和 unwrap 方法

public final byte[] wrap(Key key) 
    throws IllegalBlockSizeException, InvalidKeyException


public final Key unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType)
     throws InvalidKeyException, NoSuchAlgorithmException

wrap 方法用于包装密钥,unwrap方法用于解包一个以前包装的密钥。两者为互逆操作。

在解包时参数 wrappedKeyType 可以取三个值,它们都对应于Cipher的静态常量:

  1. PUBLIC_KEY 表示要解包的密钥为“公钥”。
  2. PRIVATE_KEY 表示要解包的密钥为“私钥”。
  3. SECRET_KEY 表示要解包的密钥为“秘密密钥”。

其他方法

  1. public final int getBlockSize() 返回块的大小(以字节为单位)。
  2. public final int getOutputSize(int inputLen)根据给定的输入长度 inputLen(以字节为单位),返回保存下一个 update 或 doFinal 操作结果所需的输出缓冲区长度(以字节为单位)。
  3. public final byte[] getIV() 返回新缓冲区中的初始化向量 (IV)
  4. public final AlgorithmParameters getParameters() 返回此 Cipher 使用的参数。返回的参数可能与初始化此 Cipher 所使用的参数相同;如果此 Cipher 需要算法参数但却未使用任何参数进行初始化,则返回的参数将由默认值和底层 Cipher 实现所使用的随机参数值组成。

algorithm 参数支持的字符串:

  1. RSA
  2. DES
  3. DESede
  4. DESedeWrap
  5. PBEWithMD5AndDES
  6. PBEWithMD5AndTripleDES
  7. PBEWithSHA1AndDESede
  8. PBEWithSHA1AndRC2_40
  9. PBEWithSHA1AndRC2_128
  10. PBEWithSHA1AndRC4_40
  11. PBEWithSHA1AndRC4_128
  12. PBEWithHmacSHA1AndAES_128
  13. PBEWithHmacSHA224AndAES_128
  14. PBEWithHmacSHA256AndAES_128
  15. PBEWithHmacSHA384AndAES_128
  16. PBEWithHmacSHA512AndAES_128
  17. PBEWithHmacSHA1AndAES_256
  18. PBEWithHmacSHA224AndAES_256
  19. PBEWithHmacSHA256AndAES_256
  20. PBEWithHmacSHA384AndAES_256
  21. PBEWithHmacSHA512AndAES_256
  22. Blowfish
  23. AES
  24. AES_128/ECB/NoPadding
  25. AES_128/CBC/NoPadding
  26. AES_128/OFB/NoPadding
  27. AES_128/CFB/NoPadding
  28. AES_128/GCM/NoPadding
  29. AES_192/ECB/NoPadding
  30. AES_192/CBC/NoPadding
  31. AES_192/OFB/NoPadding
  32. AES_192/CFB/NoPadding
  33. AES_192/GCM/NoPadding
  34. AES_256/ECB/NoPadding
  35. AES_256/CBC/NoPadding
  36. AES_256/OFB/NoPadding
  37. AES_256/CFB/NoPadding
  38. AES_256/GCM/NoPadding
  39. AESWrap
  40. AESWrap_128
  41. AESWrap_192
  42. AESWrap_256
  43. RC2
  44. ARCFOUR
  45. Blowfish
  46. RSA/ECB/PKCS1Padding
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容

  • 1. ASCII 编码 ASCII(American Standard Code for Information ...
    s酸菜阅读 8,516评论 0 8
  • 1、不安全的随机数生成,在CSRF TOKEN生成、password reset token生成等,会造成toke...
    nightmare丿阅读 3,571评论 0 1
  • 这篇文章主要讲述在Mobile BI(移动商务智能)开发过程中,在网络通信、数据存储、登录验证这几个方面涉及的加密...
    雨_树阅读 2,232评论 0 6
  • 前言 《图解密码技术》一书介绍了很多关于密码的知识,通读一遍需要不少时间。为了方便学习,我对书中关键的部分进行了总...
    咖枯阅读 7,013评论 1 25
  • 眨眼之间,高考过去十年了,这不高中和的微信群里商量着高中同学十年聚会的事情,时间就在考试完了之后的时间,我思考了很...
    剽悍的兔子阅读 292评论 0 0