java什么时候求补码_java补码算法

//这是调用的测试程序:

public static void test(){         //加密内容         String source = "加密加密加12abc";         //加密密钥         String key = "chiscdc_fsws_@%^";

String encrypt = EncryptUtil.encryptByKey(source,key);         System.out.println("加密后:"+encrypt);

String decrypt = EncryptUtil.decryptByKey(encrypt,key);         System.out.println("解密后:"+decrypt);     }

//这是 EncryptUtil :

import java.io.UnsupportedEncodingException; import java.security.SecureRandom;

import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import javax.xml.transform.Source;

public class EncryptUtil {

/**     * 密钥算法     */    private static final String ALGORITHM = "DES";    /**     * 加解密算法/工作模式/填充方式     */    private static final String ALGORITHM_STR = "DES/ECB/NoPadding";

private static final String CHARSET = "UTF-8";        /**     * 填充内容     */    private static final String PAD_STR = "\0";

/**     *

方法描述:根据自己的密钥实现des加密

    *     * @MethodAuthor yzd, 2018/7/23,encryptByKey     *     */     public static String encryptByKey(String souce, String key) {         try {             return encryptByDes(pkcs5Pad(souce), pkcs5Pad(key));         } catch (Exception e) {             e.printStackTrace();             return null;         }     }

/**     *

方法描述:根据密钥解密

    *     * @MethodAuthor yzd, 2018/7/23,decryptByKey     *     */     public static String decryptByKey(String souceString,String key) {         try {             byte [] source = hexStringToBytes(souceString);             return decryptByDes(source, pkcs5Pad(key)).trim();         } catch (Exception e) {             e.printStackTrace();             return null;         }     }

/**      *

方法描述:正式加密操作

     *      * @MethodAuthor yzd, 2018/7/23,decryptByKey      *      */    private static String encryptByDes( byte[] souce, byte[] bs)          throws Exception {       // DES算法要求有一个可信任的随机数源       SecureRandom sr = new SecureRandom();       // 从原始密匙数据创建DESKeySpec对象       DESKeySpec dks = new DESKeySpec(bs);       // 创建一个密匙工厂,然后用它把DESKeySpec转换成 一个SecretKey对象       SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);       SecretKey key1 = keyFactory.generateSecret(dks);       // Cipher对象实际完成加密操作       Cipher cipher = Cipher.getInstance(ALGORITHM_STR);       // 用密匙初始化Cipher对象       cipher.init(Cipher.ENCRYPT_MODE, key1, sr);       // 现在,获取数据并加密       byte encryptedData[] = cipher.doFinal(souce);

return byteArr2HexStr(encryptedData);    }

public static String byteArr2HexStr(byte[] arrB) {       int iLen = arrB.length;       // 每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍       StringBuffer sb = new StringBuffer(iLen * 2);       for (int i = 0; i < iLen; i++) {          int intTmp = arrB[i];          // 把负数转换为正数          while (intTmp < 0) {             intTmp = intTmp + 256;          }          // 小于0F的数需要在前面补0          if (intTmp < 16) {             sb.append("0");          }          sb.append(Integer.toString(intTmp, 16));       }       return sb.toString();    }

public static byte[] hexStringToBytes(String hexString) {         if (hexString == null) {             return null;         }        if (hexString.length() <= 0){            return new byte[0];        }         hexString = hexString.toUpperCase();         int length = hexString.length() / 2;         char[] hexChars = hexString.toCharArray();         byte[] result = new byte[length];         for (int i = 0; i < length; i++) {             int step = i * 2;             result[i] = (byte) (charToByte(hexChars[step]) << 4 | charToByte(hexChars[step + 1]));         }         return result;     }    private static final String HEX_STRING_MAPPING = "0123456789ABCDEF";    private static byte charToByte(char c) {         return (byte) HEX_STRING_MAPPING.indexOf(c);     }        private static String decryptByDes(byte[] souce, byte[] bs)          throws Exception {       // DES算法要求有一个可信任的随机数源       SecureRandom sr = new SecureRandom();       // 从原始密匙数据创建DESKeySpec对象       DESKeySpec dks = new DESKeySpec(bs);       // 创建一个密匙工厂,然后用它把DESKeySpec转换成 一个SecretKey对象       SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);       SecretKey key1 = keyFactory.generateSecret(dks);       // Cipher对象实际完成加密操作       Cipher cipher = Cipher.getInstance(ALGORITHM_STR);       // 用密匙初始化Cipher对象       cipher.init(Cipher.DECRYPT_MODE, key1, sr);

// 将加密报文用BASE64算法转化为字节数组       byte[] encryptedData =souce;       // 用DES算法解密报文       byte decryptedData[] = cipher.doFinal(encryptedData);       return new String(decryptedData, CHARSET);    }

public static byte[] hexStr2ByteArr(byte[] byIn) throws Exception {       byte[] arrB = byIn;       int iLen = arrB.length;

// 两个字符表示一个字节,所以字节数组长度是字符串长度除以2       byte[] arrOut = new byte[iLen / 2];       for (int i = 0; i < iLen; i = i + 2) {          String strTmp = new String(arrB, i, 2);          arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);       }       return arrOut;    }

/**     *

方法描述:不足8的倍数,后面追加空格

    *     * @MethodAuthor yzd, 2018/7/27,pkcs5Pad     *     */    private static byte[] pkcs5Pad(final String inSouce) {         byte[] bySource = new byte[0];         try {             bySource = inSouce.getBytes(CHARSET);

// 密文和密钥的长度必须是8的倍数             if (0 == bySource.length % 8) {                 return bySource;             }         } catch (UnsupportedEncodingException e) {             // TODO Auto-generated catch block             e.printStackTrace();         }

int length = bySource.length;         int nPaddedLength = (length / 8 + 1) * 8;         byte[] byReturn = new byte[nPaddedLength];         System.arraycopy(bySource, 0, byReturn, 0, length);         int i = length;         while (i < nPaddedLength) {             byReturn[i] = (byte) (nPaddedLength - length);             i++;         }         return byReturn;     } }

原因在于: 输入的原文必须是BYTE数据,汉字的话,使用UTF-8获取其BYTE值。

DES加密时,是需要按分组长度为8字节补齐的。

大神 小弟不才 请问 result[i] = (byte) (charToByte(hexChars[step]) << 4 | charToByte(hexChars[step + 1])); 这段是做什么的?

卧槽 可以的 大神大神 膜拜一下 谢了~

UTF-8

另外, 原代码中的pkcs5Pad的补码方式是不对的。 请参考 https://blog.csdn.net/stewart/article/details/52462273

不用楼上说的那么麻烦直接将这行代码

private static final String ALGORITHM_STR = "DES/ECB/NoPadding"

改为

public static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding ";

即可

错误原因:

DES、AES 或者 3DES 属于块加密算法,一般来说原文必须是 8 的整数倍,所以块加密算法除子加密模式之外,还涉及到一个填充模式。 如果一定要用 NoPadding 的话,那么必须保证原文字节是 8 的倍数,否则的话需要使用其他的填充模式。 在 Sun JCE 中默认的填充模式除了 NoPadding 之外,还有: PKCS5Padding 和 ISO10126Padding PKCS5Padding 的填充规则是: 填充至符合块大小的整数倍,填充值为填充数量数。例如: 原始:FF FF FF FF FF FF FF FF FF 填充:FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07 ISO10126Padding 的填充规则是: 填充至符合块大小的整数倍,填充值最后一个字节为填充的数量数,其他字节随机处理。例如: 原始:FF FF FF FF FF FF FF FF FF 填充:FF FF FF FF FF FF FF FF FF 3F 7A B4 09 14 36 07 使用填充模式后原文字节并不需要是 8 的整数倍,采用填充模式之后,块加密的密文长度为: (N / 8 * 8) + 8 如上,假如原文长度为 15 个字节,密文长度就是 16 个字节。假如原文长度为 16 个字节,密文长度就为 24 个字节。也就是说,采用填充模式后必须进行填充,哪怕是 8 的整数倍。

厉害了 都是大神啊

引用来自“melon_jj”的评论

不用楼上说的那么麻烦直接将这行代码

private static final String ALGORITHM_STR = "DES/ECB/NoPadding"

改为

public static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding ";

即可

错误原因:

DES、AES 或者 3DES 属于块加密算法,一般来说原文必须是 8 的整数倍,所以块加密算法除子加密模式之外,还涉及到一个填充模式。 如果一定要用 NoPadding 的话,那么必须保证原文字节是 8 的倍数,否则的话需要使用其他的填充模式。 在 Sun JCE 中默认的填充模式除了 NoPadding 之外,还有: PKCS5Padding 和 ISO10126Padding PKCS5Padding 的填充规则是: 填充至符合块大小的整数倍,填充值为填充数量数。例如: 原始:FF FF FF FF FF FF FF FF FF 填充:FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07 ISO10126Padding 的填充规则是: 填充至符合块大小的整数倍,填充值最后一个字节为填充的数量数,其他字节随机处理。例如: 原始:FF FF FF FF FF FF FF FF FF 填充:FF FF FF FF FF FF FF FF FF 3F 7A B4 09 14 36 07 使用填充模式后原文字节并不需要是 8 的整数倍,采用填充模式之后,块加密的密文长度为: (N / 8 * 8) + 8 如上,假如原文长度为 15 个字节,密文长度就是 16 个字节。假如原文长度为 16 个字节,密文长度就为 24 个字节。也就是说,采用填充模式后必须进行填充,哪怕是 8 的整数倍。

回复 @Jordan裔 : 需要交流学习的话可以加群826183079

回复 @Jordan裔 : 好吧

实在不好意思

我也想给你采纳 可是在你回答之前 我已经给楼上的哥们采纳过了 不能重复采纳了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值