`

JAVA上加密算法的实现用例(上)

    博客分类:
  • JAVA
阅读更多

由于实际开发对加密解密相关算法的需要,今天网搜了篇相对较全面的一篇加密算法JAVA版,这里转载一下以供大家参考。

第1章基础知识

1.1. 单钥密码体制
单钥密码体制是一种传统的加密算法,是指信息的发送方和接收方共同使用同一把密钥进行加解密。

通常,使用的加密算法比较简便高效,密钥简短,加解密速度快,破译极其困难。但是加密的安全性依靠密钥保管的安全性,在公开的计算机网络上安全地传送和保管密钥是一个严峻的问题,并且如果在多用户的情况下密钥的保管安全性也是一个问题。

单钥密码体制的代表是美国的DES

1.2. 消息摘要
一个消息摘要就是一个数据块的数字指纹。即对一个任意长度的一个数据块进行计算,产生一个唯一指印(对于SHA1是产生一个20字节的二进制数组)。

消息摘要有两个基本属性:

  • 两个不同的报文难以生成相同的摘要
  • 难以对指定的摘要生成一个报文,而由该报文反推算出该指定的摘要
代表:美国国家标准技术研究所的SHA1和麻省理工学院Ronald Rivest提出的MD5

1.3. Diffie-Hellman密钥一致协议
密钥一致协议是由公开密钥密码体制的奠基人Diffie和Hellman所提出的一种思想。

先决条件,允许两名用户在公开媒体上交换信息以生成"一致"的,可以共享的密钥

代表:指数密钥一致协议(Exponential Key Agreement Protocol)

1.4. 非对称算法与公钥体系
1976年,Dittie和Hellman为解决密钥管理问题,在他们的奠基性的工作"密码学的新方向"一文中,提出一种密钥交换协议,允许在不安全的媒体上通过通讯双方交换信息,安全地传送秘密密钥。在此新思想的基础上,很快出现了非对称密钥密码体制,即公钥密码体制。在公钥体制中,加密密钥不同于解密密钥,加密密钥公之于众,谁都可以使用;解密密钥只有解密人自己知道。它们分别称为公开密钥(Public key)和秘密密钥(Private key)。

迄今为止的所有公钥密码体系中,RSA系统是最著名、最多使用的一种。RSA公开密钥密码系统是由R.Rivest、A.Shamir和L.Adleman俊教授于1977年提出的。RSA的取名就是来自于这三位发明者的姓的第一个字母

1.5. 数字签名
所谓数字签名就是信息发送者用其私钥对从所传报文中提取出的特征数据(或称数字指纹)进行RSA算法操作,以保证发信人无法抵赖曾发过该信息(即不可抵赖性),同时也确保信息报文在经签名后末被篡改(即完整性)。当信息接收者收到报文后,就可以用发送者的公钥对数字签名进行验证。 

在数字签名中有重要作用的数字指纹是通过一类特殊的散列函数(HASH函数)生成的,对这些HASH函数的特殊要求是:

  1. 接受的输入报文数据没有长度限制;
  2. 对任何输入报文数据生成固定长度的摘要(数字指纹)输出
  3. 从报文能方便地算出摘要;
  4. 难以对指定的摘要生成一个报文,而由该报文反推算出该指定的摘要;
  5. 两个不同的报文难以生成相同的摘要


代表:DSA

第2章在JAVA中的实现

2.1. 相关
Diffie-Hellman密钥一致协议和DES程序需要JCE工具库的支持,可以到 http://java.sun.com/security/index.html 下载JCE,并进行安装。简易安装把 jce1.2.1\lib 下的所有内容复制到 %java_home%\lib\ext下,如果没有ext目录自行建立,再把jce1_2_1.jar和sunjce_provider.jar添加到CLASSPATH内,更详细说明请看相应用户手册

2.2. 消息摘要MD5和SHA的使用
使用方法:

首先用生成一个MessageDigest类,确定计算方法

java.security.MessageDigest alga=java.security.MessageDigest.getInstance("SHA-1");

添加要进行计算摘要的信息

alga.update(myinfo.getBytes());

计算出摘要

byte[] digesta=alga.digest();

发送给其他人你的信息和摘要

其他人用相同的方法初始化,添加信息,最后进行比较摘要是否相同

algb.isEqual(digesta,algb.digest())

相关AIP

java.security.MessageDigest 类

static getInstance(String algorithm)

返回一个MessageDigest对象,它实现指定的算法

参数:算法名,如 SHA-1 或MD5

void update (byte input)

void update (byte[] input)

void update(byte[] input, int offset, int len)

添加要进行计算摘要的信息

byte[] digest()

完成计算,返回计算得到的摘要(对于MD5是16位,SHA是20位)

void reset()

复位

static boolean isEqual(byte[] digesta, byte[] digestb)

比效两个摘要是否相同

java 代码
  1. import java.security.*;   
  2. public class myDigest {   
  3.   public static void main(String[] args)  {   
  4.   
  5.     myDigest my=new myDigest();   
  6.     my.testDigest();   
  7.   
  8.   }   
  9.   public void testDigest()   
  10.   {   
  11.    try {   
  12.      String myinfo="我的测试信息";   
  13.   
  14.     //java.security.MessageDigest alg=java.security.MessageDigest.getInstance("MD5");   
  15.       java.security.MessageDigest alga=java.security.MessageDigest.getInstance("SHA-1");   
  16.       alga.update(myinfo.getBytes());   
  17.       byte[] digesta=alga.digest();   
  18.       System.out.println("本信息摘要是:"+byte2hex(digesta));   
  19.       //通过某中方式传给其他人你的信息(myinfo)和摘要(digesta) 对方可以判断是否更改或传输正常   
  20.       java.security.MessageDigest algb=java.security.MessageDigest.getInstance("SHA-1");   
  21.       algb.update(myinfo.getBytes());   
  22.       if (algb.isEqual(digesta,algb.digest())) {   
  23.          System.out.println("信息检查正常");   
  24.        }   
  25.        else  
  26.         {   
  27.           System.out.println("摘要不相同");   
  28.          }   
  29.   
  30.    }   
  31.    catch (java.security.NoSuchAlgorithmException ex) {   
  32.      System.out.println("非法摘要算法");   
  33.    }   
  34.   
  35.   }   
  36.   public String byte2hex(byte[] b) //二行制转字符串   
  37.     {   
  38.      String hs="";   
  39.      String stmp="";   
  40.      for (int n=0;n
  41.       {   
  42.        stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));   
  43.        if (stmp.length()==1) hs=hs+"0"+stmp;   
  44.        else hs=hs+stmp;   
  45.        if (n1)  hs=hs+":";   
  46.       }   
  47.      return hs.toUpperCase();   
  48.     }   
  49.   
  50. }  


2.3. 数字签名DSA

  1. 对于一个用户来讲首先要生成他的密钥对,并且分别保存

    生成一个KeyPairGenerator实例

    java 代码
    1. java.security.KeyPairGenerator  keygen=java.security.KeyPairGenerator.getInstance("DSA");   
    2. //如果设定随机产生器就用如相代码初始化   
    3. SecureRandom secrand=new SecureRandom();   
    4. secrand.setSeed("tttt".getBytes()); //初始化随机产生器   
    5. keygen.initialize(512,secrand);     //初始化密钥生成器否则   
    6. keygen.initialize(512);   
    7. //生成密钥公钥pubkey和私钥prikey   
    8. KeyPair keys=keygen.generateKeyPair(); //生成密钥组   
    9. PublicKey pubkey=keys.getPublic();   
    10. PrivateKey prikey=keys.getPrivate();   
    11. //分别保存在myprikey.dat和mypubkey.dat中,以便下次不在生成   
    12. //(生成密钥对的时间比较长   
    13. java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myprikey.dat"));   
    14. out.writeObject(prikey);   
    15. out.close();   
    16. out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("mypubkey.dat"));   
    17. out.writeObject(pubkey);   
    18. out.close();  


  2. 用他私人密钥(prikey)对他所确认的信息(info)进行数字签名产生一个签名数组

    从文件中读入私人密钥(prikey)

    java 代码
    1. java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("myprikey.dat"));   
    2. PrivateKey myprikey=(PrivateKey)in.readObject();   
    3. in.close();   
    4. //初始一个Signature对象,并用私钥对信息签名   
    5. java.security.Signature signet=java.security.Signature.getInstance("DSA");   
    6. signet.initSign(myprikey);   
    7. signet.update(myinfo.getBytes());   
    8. byte[] signed=signet.sign();   
    9. //把信息和签名保存在一个文件中(myinfo.dat)   
    10. java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myinfo.dat"));   
    11. out.writeObject(myinfo);   
    12. out.writeObject(signed);   
    13. out.close();   
    14. //把他的公钥的信息及签名发给其它用户  


  3. 其他用户用他的公共密钥(pubkey)和签名(signed)和信息(info)进行验证是否由他签名的信息

    读入公钥
    java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("mypubkey.dat"));
    PublicKey pubkey=(PublicKey)in.readObject();
    in.close();

    读入签名和信息
    in=new java.io.ObjectInputStream(new java.io.FileInputStream("myinfo.dat"));
    String info=(String)in.readObject();
    byte[] signed=(byte[])in.readObject();
    in.close();

    初始一个Signature对象,并用公钥和签名进行验证
    java.security.Signature signetcheck=java.security.Signature.getInstance("DSA");
    signetcheck.initVerify(pubkey);
    signetcheck.update(info.getBytes());
    if (signetcheck.verify(signed)) { System.out.println("签名正常");}

    对于密钥的保存本文是用对象流的方式保存和传送的,也可可以用编码的方式保存.注意要
    import java.security.spec.*
    import java.security.*

    具休说明如下

    • public key是用X.509编码的,例码如下:
      java 代码
      1. byte[] bobEncodedPubKey=mypublic.getEncoded(); //生成编码   
      2. //传送二进制编码   
      3. //以下代码转换编码为相应key对象   
      4. X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bobEncodedPubKey);   
      5. KeyFactory keyFactory = KeyFactory.getInstance("DSA");   
      6. PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec);  
    • 对于Private key是用PKCS#8编码,例码如下:
      java 代码
      1. byte[] bPKCS=myprikey.getEncoded();   
      2. //传送二进制编码   
      3. //以下代码转换编码为相应key对象   
      4. PKCS8EncodedKeySpec priPKCS8=new PKCS8EncodedKeySpec(bPKCS);   
      5. KeyFactory keyf=KeyFactory.getInstance("DSA");   
      6. PrivateKey otherprikey=keyf.generatePrivate(priPKCS8);  


  4. 常用API

    java.security.KeyPairGenerator 密钥生成器类
    public static KeyPairGenerator getInstance(String algorithm) throws NoSuchAlgorithmException
    以指定的算法返回一个KeyPairGenerator 对象
    参数: algorithm 算法名.如:"DSA","RSA"

    public void initialize(int keysize)

    以指定的长度初始化KeyPairGenerator对象,如果没有初始化系统以1024长度默认设置

    参数:keysize 算法位长.其范围必须在 512 到 1024 之间,且必须为 64 的倍数

    public void initialize(int keysize, SecureRandom random)
    以指定的长度初始化和随机发生器初始化KeyPairGenerator对象
    参数:keysize 算法位长.其范围必须在 512 到 1024 之间,且必须为 64 的倍数
    random 一个随机位的来源(对于initialize(int keysize)使用了默认随机器

    public abstract KeyPair generateKeyPair()
    产生新密钥对

    java.security.KeyPair 密钥对类
    public PrivateKey getPrivate()
    返回私钥

    public PublicKey getPublic()
    返回公钥

    java.security.Signature 签名类
    public static Signature getInstance(String algorithm) throws NoSuchAlgorithmException
    返回一个指定算法的Signature对象
    参数 algorithm 如:"DSA"

    public final void initSign(PrivateKey privateKey)
    throws InvalidKeyException
    用指定的私钥初始化
    参数:privateKey 所进行签名时用的私钥

    public final void update(byte data)
    throws SignatureException
    public final void update(byte[] data)
    throws SignatureException
    public final void update(byte[] data, int off, int len)
    throws SignatureException
    添加要签名的信息

    public final byte[] sign()
    throws SignatureException
    返回签名的数组,前提是initSign和update

    public final void initVerify(PublicKey publicKey)
    throws InvalidKeyException
    用指定的公钥初始化
    参数:publicKey 验证时用的公钥

    public final boolean verify(byte[] signature)
    throws SignatureException
    验证签名是否有效,前提是已经initVerify初始化
    参数: signature 签名数组

    java 代码
    1. import java.security.*;   
    2. import java.security.spec.*;   
    3.   
    4. public class testdsa {   
    5.     public static void main(String[] args)   
    6.             throws java.security.NoSuchAlgorithmException, java.lang.Exception {   
    7.         testdsa my = new testdsa();   
    8.         my.run();   
    9.     }   
    10.   
    11.     public void run() {   
    12.   
    13.         // 数字签名生成密钥   
    14.         // 第一步生成密钥对,如果已经生成过,本过程就可以跳过,对用户来讲myprikey.dat要保存在本地   
    15.         // 而mypubkey.dat给发布给其它用户   
    16.         if ((new java.io.File("myprikey.dat")).exists() == false) {   
    17.             if (generatekey() == false) {   
    18.                 System.out.println("生成密钥对败");   
    19.                 return;   
    20.             }   
    21.             ;   
    22.         }   
    23.         // 第二步,此用户   
    24.         // 从文件中读入私钥,对一个字符串进行签名后保存在一个文件(myinfo.dat)中   
    25.         // 并且再把myinfo.dat发送出去   
    26.         // 为了方便数字签名也放进了myifno.dat文件中,当然也可分别发送   
    27.         try {   
    28.             java.io.ObjectInputStream in = new java.io.ObjectInputStream(   
    29.                     new java.io.FileInputStream("myprikey.dat"));   
    30.             PrivateKey myprikey = (PrivateKey) in.readObject();   
    31.             in.close();   
    32.   
    33.             // java.security.spec.X509EncodedKeySpec pubX509=new   
    34.             // java.security.spec.X509EncodedKeySpec(bX509);   
    35.   
    36.             // java.security.spec.X509EncodedKeySpec   
    37.             // pubkeyEncode=java.security.spec.X509EncodedKeySpec   
    38.             String myinfo = "这是我的信息"// 要签名的信息   
    39.             // 用私钥对信息生成数字签名   
    40.             java.security.Signature signet = java.security.Signature   
    41.                     .getInstance("DSA");   
    42.             signet.initSign(myprikey);   
    43.             signet.update(myinfo.getBytes());   
    44.             byte[] signed = signet.sign(); // 对信息的数字签名   
    45.             System.out.println("signed(签名内容)=" + byte2hex(signed));   
    46.             // 把信息和数字签名保存在一个文件中   
    47.             java.io.ObjectOutputStream out = new java.io.ObjectOutputStream(   
    48.                     new java.io.FileOutputStream("myinfo.dat"));   
    49.             out.writeObject(myinfo);   
    50.             out.writeObject(signed);   
    51.             out.close();   
    52.             System.out.println("签名并生成文件成功");   
    53.         } catch (java.lang.Exception e) {   
    54.             e.printStackTrace();   
    55.             System.out.println("签名并生成文件失败");   
    56.         }   
    57.         ;   
    58.   
    59.         // 第三步   
    60.         // 其他人通过公共方式得到此户的公钥和文件   
    61.         // 其他人用此户的公钥,对文件进行检查,如果成功说明是此用户发布的信息.   
    62.         //   
    63.         try {   
    64.   
    65.             java.io.ObjectInputStream in = new java.io.ObjectInputStream(   
    66.                     new java.io.FileInputStream("mypubkey.dat"));   
    67.             PublicKey pubkey = (PublicKey) in.readObject();   
    68.             in.close();   
    69.             System.out.println(pubkey.getFormat());   
    70.   
    71.             in = new java.io.ObjectInputStream(new java.io.FileInputStream(   
    72.                     "myinfo.dat"));   
    73.             String info = (String) in.readObject();   
    74.             byte[] signed = (byte[]) in.readObject();   
    75.             in.close();   
    76.   
    77.             java.security.Signature signetcheck = java.security.Signature   
    78.                     .getInstance("DSA");   
    79.             signetcheck.initVerify(pubkey);   
    80.             signetcheck.update(info.getBytes());   
    81.             if (signetcheck.verify(signed)) {   
    82.                 System.out.println("info=" + info);   
    83.                 System.out.println("签名正常");   
    84.             } else  
    85.                 System.out.println("非签名正常");   
    86.         } catch (java.lang.Exception e) {   
    87.             e.printStackTrace();   
    88.         }   
    89.         ;   
    90.   
    91.     }   
    92.   
    93.     // 生成一对文件myprikey.dat和mypubkey.dat---私钥和公钥,   
    94.     // 公钥要用户发送(文件,网络等方法)给其它用户,私钥保存在本地   
    95.     public boolean generatekey() {   
    96.         try {   
    97.             java.security.KeyPairGenerator keygen = java.security.KeyPairGenerator   
    98.                     .getInstance("DSA");   
    99.             // SecureRandom secrand=new SecureRandom();   
    100.             // secrand.setSeed("tttt".getBytes()); //初始化随机产生器   
    101.             // keygen.initialize(576,secrand); //初始化密钥生成器   
    102.             keygen.initialize(512);   
    103.             KeyPair keys = keygen.genKeyPair();   
    104.             // KeyPair keys=keygen.generateKeyPair(); //生成密钥组   
    105.             PublicKey pubkey = keys.getPublic();   
    106.             PrivateKey prikey = keys.getPrivate();   
    107.   
    108.             java.io.ObjectOutputStream out = new java.io.ObjectOutputStream(   
    109.                     new java.io.FileOutputStream("myprikey.dat"));   
    110.             out.writeObject(prikey);   
    111.             out.close();   
    112.             System.out.println("写入对象 prikeys ok");   
    113.             out = new java.io.ObjectOutputStream(new java.io.FileOutputStream(   
    114.                     "mypubkey.dat"));   
    115.             out.writeObject(pubkey);   
    116.             out.close();   
    117.             System.out.println("写入对象 pubkeys ok");   
    118.             System.out.println("生成密钥对成功");   
    119.             return true;   
    120.         } catch (java.lang.Exception e) {   
    121.             e.printStackTrace();   
    122.             System.out.println("生成密钥对失败");   
    123.             return false;   
    124.         }   
    125.         ;   
    126.   
    127.     }   
    128.   
    129.     public String byte2hex(byte[] b) {   
    130.         String hs = "";   
    131.         String stmp = "";   
    132.         for (int n = 0; n < b.length; n++) {   
    133.             stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));   
    134.             if (stmp.length() == 1)   
    135.                 hs = hs + "0" + stmp;   
    136.             else  
    137.                 hs = hs + stmp;   
    138.             if (n < b.length - 1)   
    139.                 hs = hs + ":";   
    140.         }   
    141.         return hs.toUpperCase();   
    142.     }   
    143. }  

分享到:
评论

相关推荐

    JAVA上加密算法的实现用例.doc

    在Java中实现加密算法涉及到多个重要的概念和技术,包括单钥密码体制、消息摘要、Diffie-Hellman密钥一致协议、非对称算法和公钥体系以及数字签名。下面将详细阐述这些知识点。 **1. 单钥密码体制** 单钥密码体制,...

    JAVA上加密算法的实现用例.rar

    这个RAR压缩包文件“JAVA上加密算法的实现用例”包含了一个PDF文档,很可能是详细介绍了如何在Java环境中应用各种加密算法的实际案例。虽然没有具体的标签提供额外的信息,但我们可以基于通常的加密算法来探讨相关...

    JAVA上加密算法的实现用例.rar_java 加密_加密_加密算法 java

    四、Java加密算法实现步骤 1. 导入相关类库:如`javax.crypto.Cipher`、`java.security.KeyPairGenerator`等。 2. 选择加密算法:如AES、RSA等。 3. 初始化Cipher对象:根据加密模式(ECB、CBC等)和填充模式...

    IBM JAVA上加密算法的实现用例.rar_Java加密_加密算法

    本案例主要探讨了IBM Java平台上如何实现加密算法,这对于开发人员来说是一个非常实用的技术点。 首先,我们要了解加密的基本概念。加密是将明文(可读数据)转化为密文(不可读数据)的过程,目的是保护信息不被...

    信息安全实习一古典加密算法 实现swing图形化

    在信息安全领域,实习项目往往是为了让学生深入理解和应用理论知识,本次实习的主题是“古典加密算法的实现”,并结合了Java的Swing库来构建图形用户界面(GUI)。实习旨在通过实际操作,帮助实习生掌握密码学的基本...

    AES加密算法java实现及实验报告

    1. **实验目的**:理解AES加密算法的基本原理,掌握Java实现AES加密的步骤。 2. **实验环境**:列出所使用的开发工具、Java版本等信息。 3. **实验步骤**:详细描述如何生成密钥、加密和解密过程,以及代码实现。 4....

    背包加密JavaDemo

    【压缩包子文件的文件名称列表】:"BagEncriptDemo"可能是博主提供的一个Java源代码示例文件,该文件可能包含了整个背包加密算法的实现,包括公钥和私钥的生成、加密和解密的函数,以及可能的测试用例。 总的来说,...

    SM2&SM3;&SM4;国密算法Java实现

    国密算法Java实现(含详细测试代码) 我自己按照国密文档通过Java实现SM2密码算法加密/解密、签名验签,SM3密码杂凑算法,SM4分组密码算法ECB、CBC模式加密/解密。 经过详尽的测试过后没有发现问题,但建议大家在...

    JAVA源码很强的Java加密解密算法源码

    综上所述,“JAVA源码很强的Java加密解密算法源码”这一主题涵盖了加密解密的基本概念、应用场景以及具体的实现方法等内容。对于Java开发者而言,深入学习这些知识不仅有助于提升自己的技术水平,还能更好地应对实际...

    基于java实现DES算法加密报告相关

    以下是关于DES加密算法以及Java实现的相关知识点: 1. **DES算法概述** DES是一种块加密算法,它使用56位的密钥对64位的数据块进行加密。由于其固定长度的密钥和数据块,DES在处理大量数据时可能效率较低,且56位...

    DES加密算法JAVA实现(带简单界面)

    在Java中实现DES加密算法,需要使用Java Cryptography Extension (JCE) 提供的相关类库,主要包括`javax.crypto.Cipher`、`java.security.SecureRandom`以及`java.security.Key`等。以下是一个简单的DESEncryption类...

    java前后端通讯AES加密及解密样例

    本文将深入探讨在Java环境下,特别是在前后端通信中如何使用AES(Advanced Encryption Standard)加密算法进行数据的安全传输。我们将基于Spring Boot框架来构建一个实际示例,演示AES的加密与解密过程。 AES,全称...

Global site tag (gtag.js) - Google Analytics