DES和RSA算法的java实现

1、对称加密算法

      对称加密算法是应用较早的加密算法,技术成熟。在对称加密算法中,数据发信方将明文(原始数据)和加密密钥一块儿通过特殊加密算法处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若想解读原文,则须要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。在对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密,这就要求解密方事先必须知道加密密钥。java

      对称加密算法的优势是:算法公开、计算量小、加密速度快、加密效率高。缺点是:首先,交易双方都使用一样钥匙,安全性得不到保证。其次,每对用户每次使用对称加密算法时,都须要使用其余人不知道的唯一钥匙,这会使得发收信双方所拥有的钥匙数量呈几何级数增加,密钥管理成为用户的负担。对称加密算法在分布式网络系统上使用较为困难,主要是由于密钥管理困难,使用成本较高。算法

1.DES算法

      DES算法是最流行的对称加密算法,全称是Data Encryption Standard,即数据加密算法,它是IBM公司于1975年研究成功并公开发表的。DES算法的入口参数有三个:Key、Data、Mode。其中Key为8个字节共64位,是DES算法的工做密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工做方式,有两种:加密或解密。编程

      能够对数据进行三次DES算法,从而造成3DES算法。此算法至关因而对每一个数据块应用三次DES加密算法。因为计算机运算能力的加强,原版DES密码的密钥长度变得容易被暴力破解;3DES便是设计用来提供一种相对简单的方法,即经过增长DES的密钥长度来避免相似的攻击,而不是设计一种全新的块密码算法。对此算法的介绍,本文后面再也不赘述。数组

a.算法原理安全

      DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位,其算法主要分为两步:网络

1.初始置换框架

      其功能是把输入的64位数据块按位从新组合,并把输出分为L0、R0两部分,每部分各长32位,其置换规则为将输入的第58位换到第一位,第50位换到第2位……依此类推,最后一位是原来的第7位。L0、R0则是换位输出后的两部分,L0是输出的左32位,R0是右32位,例:设置换前的输入值为D1D2D3……D64,则通过初始置换后的结果为:L0=D58D50……D8;R0=D57D49……D7。dom

2.逆置换编程语言

      通过16次迭代运算后,获得L1六、R16,将此做为输入,进行逆置换,逆置换正好是初始置换的逆运算,由此即获得密文输出。分布式

b.DES算法在Java中的实现及运用

      Java中为安全框架提供类和接口。JDK 安全 API 是 Java 编程语言的核心 API,位于 java.security 包(及其子包),以及sun.securityAPI包(及其子包)中。设计用于帮助开发人员在程序中同时使用低级和高级安全功能。

应用实例:

    

    private static int parse(char c) {
        if (c >= 'a')
            return (c - 'a' + 10) & 0x0f;
        if (c >= 'A')
            return (c - 'A' + 10) & 0x0f;
        return (c - '0') & 0x0f;
    }

    // 从十六进制字符串到字节数组转换
    public static byte[] HexString2Bytes(String hexstr) {
        byte[] b = new byte[hexstr.length() / 2];
        int j = 0;
        for (int i = 0; i < b.length; i++) {
            char c0 = hexstr.charAt(j++);
            char c1 = hexstr.charAt(j++);
            b[i] = (byte) ((parse(c0) << 4) | parse(c1));
        }
        return b;
    }

    private static SecretKey keyGenerator(String keyStr) throws Exception {
        byte input[] = HexString2Bytes(keyStr);
        DESKeySpec desKey = new DESKeySpec(input);
        // 建立一个密匙工厂,而后用它把DESKeySpec转换成
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(desKey);
        return securekey;
    }

    // 加密
    public static String encrypt(String data, String key) throws Exception {
        Key deskey = keyGenerator(key);
        // 实例化Cipher对象,它用于完成实际的加密操做
        Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
        SecureRandom random = new SecureRandom();
        // 初始化Cipher对象,设置为加密模式
        cipher.init(Cipher.ENCRYPT_MODE, deskey, random);
        byte[] results = cipher.doFinal(data.getBytes());
        // 执行加密操做。加密后的结果一般都会用Base64编码进行传输
        return Base64.encodeBase64String(results);
    }

    // 解密
    public static String decrypt(String data, String key) throws Exception {
        Key deskey = keyGenerator(key);
        Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
        // 初始化Cipher对象,设置为解密模式
        cipher.init(Cipher.DECRYPT_MODE, deskey);
        // 执行解密操做
        return new String(cipher.doFinal(Base64.decodeBase64(data)));
    }

 

2、非对称加密算法

      非对称加密算法的核心源于数学问题,它存在公钥和私钥的概念,要完成加解密操做,须要两个密钥同时参与。

      非对称密码体制的特色:算法强度复杂、安全性依赖于算法与密钥可是因为其算法复杂,而使得加密解密速度没有对称加密解密的速度快。对称密码体制中只有一种密钥,而且是非公开的,若是要解密就得让对方知道密钥。因此保证其安全性就是保证密钥的安全,而非对称密钥体制有两种密钥,其中一个是公开的,这样就能够不须要像对称密码那样传输对方的密钥了。这样安全性就大了不少。

1.RSA算法

      RSA加密算法是一种典型的非对称加密算法,它基于大数的因式分解数学难题,它也是应用最普遍的非对称加密算法,于1978年由美国麻省理工学院(MIT)的三位学着:Ron Rivest、Adi Shamir 和 Leonard Adleman 共同提出。

a.算法原理

      RSA的原理较为简单。咱们假设有消息发送方A和消息接收方B,经过下面的几个步骤,咱们就能够完成消息的加密传递:

         1)消息发送方A在本地构建密钥对,公钥和私钥;

         2)消息发送方A将产生的公钥发送给消息接收方B;

         3)B向A发送数据时,经过公钥进行加密,A接收到数据后经过私钥进行解密,完成一次通讯;

         4)反之,A向B发送数据时,经过私钥对数据进行加密,B接收到数据后经过公钥进行解密。

      因为公钥是消息发送方A暴露给消息接收方B的,因此这种方式也存在必定的安全隐患,若是公钥在数据传输过程当中泄漏,则A经过私钥加密的数据就可能被解密。

      若是要创建更安全的加密消息传递模型,须要消息发送方和消息接收方各构建一套密钥对,并分别将各自的公钥暴露给对方,在进行消息传递时,A经过B的公钥对数据加密,B接收到消息经过B的私钥进行解密,反之,B经过A的公钥进行加密,A接收到消息后经过A的私钥进行解密。

      固然,这种方式可能存在数据传递被模拟的隐患,咱们能够经过数字签名等技术进行安全性的进一步提高。因为存在屡次的非对称加解密,这种方式带来的效率问题也更加严重。

DES算法在Java中的实现及运用:   

 // 用私钥对信息生成数字签名
    public static String sign(byte[] data, String privateKey) throws Exception {
        // 解密由base64编码的私钥
        byte[] keyBytes = decryptBASE64(privateKey);
        // 构造PKCS8EncodedKeySpec对象
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        // 取私钥匙对象
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
        // 用私钥对信息生成数字签名
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initSign(priKey);
        signature.update(data);
        return encryptBASE64(signature.sign());
    }

    // 校验数字签名
    public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
        // 解密由base64编码的公钥
        byte[] keyBytes = decryptBASE64(publicKey);
        // 构造X509EncodedKeySpec对象
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        // 取公钥匙对象
        PublicKey pubKey = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initVerify(pubKey);
        signature.update(data);
        // 验证签名是否正常
        return signature.verify(decryptBASE64(sign));
    }

    // 对私钥解密
    public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
        // 对密钥解密
        byte[] keyBytes = decryptBASE64(key);
        // 取得私钥
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        // 对数据解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }

    // 用公钥解密
    public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception {
        // 对密钥解密
        byte[] keyBytes = decryptBASE64(key);
        // 取得公钥
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key publicKey = keyFactory.generatePublic(x509KeySpec);
        // 对数据解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }

    // 用公钥加密
    public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception {
        // 对公钥解密
        byte[] keyBytes = decryptBASE64(key);
        // 取得公钥
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key publicKey = keyFactory.generatePublic(x509KeySpec);
        // 对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }

    // 用私钥加密
    public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception {
        // 对密钥解密
        byte[] keyBytes = decryptBASE64(key);
        // 取得私钥
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        // 对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }

    // 取得私钥
    public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
        Key key = (Key) keyMap.get("RSAPrivateKey");
        return encryptBASE64(key.getEncoded());
    }

    // 取得公钥
    public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
        Key key = (Key) keyMap.get("RSAPublicKey");
        return encryptBASE64(key.getEncoded());
    }

    // 初始化密钥
    public static Map<String, Object> initKey() throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        keyPairGen.initialize(1024);
        KeyPair keyPair = keyPairGen.generateKeyPair();
        // 公钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        // 私钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        Map<String, Object> keyMap = new HashMap<String, Object>(2);
        keyMap.put("RSAPublicKey", publicKey);
        keyMap.put("RSAPrivateKey", privateKey);
        return keyMap;
    }
    /**  
     * BASE64解密  
     *   
     * @param key  
     * @return  
     * @throws Exception  
     */    
    public static byte[] decryptBASE64(String key) throws Exception {    
        return (new BASE64Decoder()).decodeBuffer(key);    
    }    
        
    /**  
     * BASE64加密  
     *   
     * @param key  
     * @return        * @throws Exception        */         public static String encryptBASE64(byte[] key) throws Exception {             return (new BASE64Encoder()).encodeBuffer(key);         }    

相关文章
相关标签/搜索