Java加密技术(六)

xiaoxiao2026-06-14  7

接下来我们介绍DSA数字签名,非对称加密的另一种实现。 DSA DSA-Digital Signature Algorithm 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。数字签名,是单向加密的升级! 通过java代码实现如下: Coder类见 Java加密技术(一) Java代码 import java.security.Key;    import java.security.KeyFactory;    import java.security.KeyPair;    import java.security.KeyPairGenerator;    import java.security.PrivateKey;    import java.security.PublicKey;    import java.security.SecureRandom;    import java.security.Signature;    import java.security.interfaces.DSAPrivateKey;    import java.security.interfaces.DSAPublicKey;    import java.security.spec.PKCS8EncodedKeySpec;    import java.security.spec.X509EncodedKeySpec;    import java.util.HashMap;    import java.util.Map;       /**   * DSA安全编码组件   *    * @author 梁栋   * @version 1.0   * @since 1.0   */   public abstract class DSACoder extends Coder {           public static final String ALGORITHM = "DSA";           /**       * 默认密钥字节数       *        * <pre>       * DSA        * Default Keysize 1024         * Keysize must be a multiple of 64, ranging from 512 to 1024 (inclusive).       * </pre>       */       private static final int KEY_SIZE = 1024;           /**       * 默认种子       */       private static final String DEFAULT_SEED = "0f22507a10bbddd07d8a3082122966e3";           private static final String PUBLIC_KEY = "DSAPublicKey";        private static final String PRIVATE_KEY = "DSAPrivateKey";           /**       * 用私钥对信息生成数字签名       *        * @param data       *            加密数据       * @param privateKey       *            私钥       *        * @return       * @throws Exception       */       public static String sign(byte[] data, String privateKey) throws Exception {            // 解密由base64编码的私钥            byte[] keyBytes = decryptBASE64(privateKey);               // 构造PKCS8EncodedKeySpec对象            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);               // KEY_ALGORITHM 指定的加密算法            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);              // 取私钥匙对象            PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);              // 用私钥对信息生成数字签名            Signature signature = Signature.getInstance(keyFactory.getAlgorithm());           signature.initSign(priKey);           signature.update(data);              return encryptBASE64(signature.sign());        }          /**       * 校验数字签名       *        * @param data       *            加密数据       * @param publicKey       *            公钥       * @param sign       *            数字签名       *        * @return 校验成功返回true 失败返回false       * @throws Exception       *        */       public static boolean verify(byte[] data, String publicKey, String sign)                throws Exception {               // 解密由base64编码的公钥            byte[] keyBytes = decryptBASE64(publicKey);               // 构造X509EncodedKeySpec对象            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);               // ALGORITHM 指定的加密算法            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);              // 取公钥匙对象            PublicKey pubKey = keyFactory.generatePublic(keySpec);             Signature signature = Signature.getInstance(keyFactory.getAlgorithm());           signature.initVerify(pubKey);           signature.update(data);              // 验证签名是否正常            return signature.verify(decryptBASE64(sign));        }          /**       * 生成密钥       *        * @param seed       *            种子       * @return 密钥对象       * @throws Exception       */       public static Map<String, Object> initKey(String seed) throws Exception {            KeyPairGenerator keygen = KeyPairGenerator.getInstance(ALGORITHM);            // 初始化随机产生器            SecureRandom secureRandom = new SecureRandom();            secureRandom.setSeed(seed.getBytes());           keygen.initialize(KEY_SIZE, secureRandom);             KeyPair keys = keygen.genKeyPair();             DSAPublicKey publicKey = (DSAPublicKey) keys.getPublic();           DSAPrivateKey privateKey = (DSAPrivateKey) keys.getPrivate();              Map<String, Object> map = new HashMap<String, Object>(2);            map.put(PUBLIC_KEY, publicKey);           map.put(PRIVATE_KEY, privateKey);              return map;        }          /**       * 默认生成密钥       *        * @return 密钥对象       * @throws Exception       */       public static Map<String, Object> initKey() throws Exception {            return initKey(DEFAULT_SEED);        }          /**       * 取得私钥       *        * @param keyMap       * @return       * @throws Exception       */       public static String getPrivateKey(Map<String, Object> keyMap)                throws Exception {            Key key = (Key) keyMap.get(PRIVATE_KEY);              return encryptBASE64(key.getEncoded());        }          /**       * 取得公钥       *        * @param keyMap       * @return       * @throws Exception       */       public static String getPublicKey(Map<String, Object> keyMap)                throws Exception {            Key key = (Key) keyMap.get(PUBLIC_KEY);              return encryptBASE64(key.getEncoded());        }   }   import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.DSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; /** * DSA安全编码组件 * * @author 梁栋 * @version 1.0 * @since 1.0 */ public abstract class DSACoder extends Coder { public static final String ALGORITHM = "DSA"; /** * 默认密钥字节数 * * <pre> * DSA * Default Keysize 1024 * Keysize must be a multiple of 64, ranging from 512 to 1024 (inclusive). * </pre> */ private static final int KEY_SIZE = 1024; /** * 默认种子 */ private static final String DEFAULT_SEED = "0f22507a10bbddd07d8a3082122966e3"; private static final String PUBLIC_KEY = "DSAPublicKey"; private static final String PRIVATE_KEY = "DSAPrivateKey"; /** * 用私钥对信息生成数字签名 * * @param data * 加密数据 * @param privateKey * 私钥 * * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { // 解密由base64编码的私钥 byte[] keyBytes = decryptBASE64(privateKey); // 构造PKCS8EncodedKeySpec对象 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); // 取私钥匙对象 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 用私钥对信息生成数字签名 Signature signature = Signature.getInstance(keyFactory.getAlgorithm()); signature.initSign(priKey); signature.update(data); return encryptBASE64(signature.sign()); } /** * 校验数字签名 * * @param data * 加密数据 * @param publicKey * 公钥 * @param sign * 数字签名 * * @return 校验成功返回true 失败返回false * @throws Exception * */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { // 解密由base64编码的公钥 byte[] keyBytes = decryptBASE64(publicKey); // 构造X509EncodedKeySpec对象 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); // ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); // 取公钥匙对象 PublicKey pubKey = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(keyFactory.getAlgorithm()); signature.initVerify(pubKey); signature.update(data); // 验证签名是否正常 return signature.verify(decryptBASE64(sign)); } /** * 生成密钥 * * @param seed * 种子 * @return 密钥对象 * @throws Exception */ public static Map<String, Object> initKey(String seed) throws Exception { KeyPairGenerator keygen = KeyPairGenerator.getInstance(ALGORITHM); // 初始化随机产生器 SecureRandom secureRandom = new SecureRandom(); secureRandom.setSeed(seed.getBytes()); keygen.initialize(KEY_SIZE, secureRandom); KeyPair keys = keygen.genKeyPair(); DSAPublicKey publicKey = (DSAPublicKey) keys.getPublic(); DSAPrivateKey privateKey = (DSAPrivateKey) keys.getPrivate(); Map<String, Object> map = new HashMap<String, Object>(2); map.put(PUBLIC_KEY, publicKey); map.put(PRIVATE_KEY, privateKey); return map; } /** * 默认生成密钥 * * @return 密钥对象 * @throws Exception */ public static Map<String, Object> initKey() throws Exception { return initKey(DEFAULT_SEED); } /** * 取得私钥 * * @param keyMap * @return * @throws Exception */ public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return encryptBASE64(key.getEncoded()); } /** * 取得公钥 * * @param keyMap * @return * @throws Exception */ public static String getPublicKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return encryptBASE64(key.getEncoded()); } } 再给出一个测试类: Java代码 import static org.junit.Assert.*;      import java.util.Map;       import org.junit.Test;       /**   *    * @author 梁栋   * @version 1.0   * @since 1.0   */   public class DSACoderTest {           @Test       public void test() throws Exception {            String inputStr = "abc";            byte[] data = inputStr.getBytes();               // 构建密钥            Map<String, Object> keyMap = DSACoder.initKey();              // 获得密钥            String publicKey = DSACoder.getPublicKey(keyMap);           String privateKey = DSACoder.getPrivateKey(keyMap);              System.err.println("公钥:\r" + publicKey);            System.err.println("私钥:\r" + privateKey);               // 产生签名            String sign = DSACoder.sign(data, privateKey);            System.err.println("签名:\r" + sign);               // 验证签名            boolean status = DSACoder.verify(data, publicKey, sign);            System.err.println("状态:\r" + status);            assertTrue(status);         }     }   import static org.junit.Assert.*; import java.util.Map; import org.junit.Test; /** * * @author 梁栋 * @version 1.0 * @since 1.0 */ public class DSACoderTest { @Test public void test() throws Exception { String inputStr = "abc"; byte[] data = inputStr.getBytes(); // 构建密钥 Map<String, Object> keyMap = DSACoder.initKey(); // 获得密钥 String publicKey = DSACoder.getPublicKey(keyMap); String privateKey = DSACoder.getPrivateKey(keyMap); System.err.println("公钥:\r" + publicKey); System.err.println("私钥:\r" + privateKey); // 产生签名 String sign = DSACoder.sign(data, privateKey); System.err.println("签名:\r" + sign); // 验证签名 boolean status = DSACoder.verify(data, publicKey, sign); System.err.println("状态:\r" + status); assertTrue(status); } } 控制台输出: Console代码 公钥:   MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZp   RV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fn   xqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuE   C/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJ   FnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImo   g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAIu4RUlcQLp49PI0MrbssOY+3uySVnp0TULSv   5T4VaHoKzsLHgGTrwOvsGA+V3yCNl2WDu3D84bSLF7liTWgOj+SMOEaPk4VyRTlLXZWGPsf1Mfd9   21XAbMeVyKDSHHVGbMjBScajf3bXooYQMlyoHiOt/WrCo+mv7efstMM0PGo=     私钥:   MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2   USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4   O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmC   ouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCB   gLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhR   kImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFwIVAIegLUtmm2oQKQJTOiLugHTSjl/q     签名:   MC0CFQCMg0J/uZmF8GuRpr3TNq48w60nDwIUJCyYNah+HtbU6NcQfy8Ac6LeLQs=     状态:   true   公钥: MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZp RV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fn xqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuE C/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJ FnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImo g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAIu4RUlcQLp49PI0MrbssOY+3uySVnp0TULSv 5T4VaHoKzsLHgGTrwOvsGA+V3yCNl2WDu3D84bSLF7liTWgOj+SMOEaPk4VyRTlLXZWGPsf1Mfd9 21XAbMeVyKDSHHVGbMjBScajf3bXooYQMlyoHiOt/WrCo+mv7efstMM0PGo= 私钥: MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2 USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4 O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmC ouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCB gLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhR kImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFwIVAIegLUtmm2oQKQJTOiLugHTSjl/q 签名: MC0CFQCMg0J/uZmF8GuRpr3TNq48w60nDwIUJCyYNah+HtbU6NcQfy8Ac6LeLQs= 状态: true 注意状态为true,就验证成功!
转载请注明原文地址: https://www.6miu.com/read-5050140.html

最新回复(0)