• 使用JAVA数字证书做数字签名认证


    1.

      keytool -genkey -keystore chinajavaworld.keystore -alias chinajavaworld

      这个命令用来产生一个密匙库,执行完毕后会在当前操作目录中产生一个chinajavaworld.keystore的文件,在执行命令的时候还有提示你输入密匙库的密码,要记住,后面还要用到。

    2.

      keytool -export -keystore chinajavaworld.keystore

      -alias chinajavaworld -file chinajavaworld.cer

      这个命令用来产生签名时所要用的证书。

    3.在JAVA里操作,将Cer内容改为BASE64编码

      

    //从密钥库中读取CA证书
    
      String storepass = "123456";
    
      //前面设置的密码
    
      FileInputStream in = new FileInputStream("e:\\license\\a\\chinajavaworld.keystore"); KeyStore ks = KeyStore.getInstance("JKS"); ks.load(in, storepass.toCharArray());
    
      //获取证书 java.security.cert.Certificate c1 = ks.getCertificate("chinajavaworld");
    
      //BASE64编码 System.out.println(StringUtils.encodeBase64(c1.getEncoded()));
    
      //将chinajavaworld.cer内容改为这里输出的内容
    

    4.开始产生(测试)签名

      

    Signature signature;
    
      try {
    
      InputStream streamCert = new java.io.FileInputStream( "e:\\license\\a\\test.cer");
    
      CertificateFactory factory = CertificateFactory.getInstance("X.509");
    
      Certificate cert = factory.generateCertificate(streamCert);
    
      System.out.println(StringUtils.encodeBase64(cert.getEncoded()));
    
      signature = Signature.getInstance("SHA1withDSA");
    
      signature.initVerify(cert.getPublicKey());
    
      //要签名的指纹内容
    
      String sss = "Welcome to www.chinajavaworld.com,The java world for you forever.";
    
      //获取CA证书私钥
    
      PrivateKey priKey=(PrivateKey)ks.getKey("test",storepass.toCharArray());
    
      System.out.println("priKey:"+StringUtils.encodeHex(priKey.getEncoded()));
    
      //用私钥签名
    
      sig = Signature.getInstance("SHA1withDSA");
    
      sig.initSign(priKey);
    
      ByteArrayOutputStream streamRaw0 = new ByteArrayOutputStream();
    
      DataOutputStream streamSig0 = new DataOutputStream(streamRaw0);
    
      streamSig0.writeUTF(sss); sig.update(streamRaw0.toByteArray());
    
      String signatureS = StringUtils.encodeHex(sig.sign());
    
      System.out.println("signature: "+signatureS);
    
      //用公钥做验证测试
    
      System.out.println("pubKey:"+StringUtils.encodeHex(cert.getPublicKey().getEncoded()));
    
      ByteArrayOutputStream streamRaw = new ByteArrayOutputStream();
    
      DataOutputStream streamSig = new DataOutputStream(streamRaw);
    
      streamSig.writeUTF(sss); signature.update(streamRaw.toByteArray());
    
      System.out.println("verify: "+signature.verify(StringUtils.decodeHex(signatureS)));
    
      } catch(Exception e)
    
      {
    
      System.out.println(e);
    
      }
    

      接下来,你就可以把chinajavaworld.cer和签名放在你的产品目录里了。认证的时候读取cer证书中的公钥,对签名内容进行认证就可以了。

      

    public static String encodeBase64(byte data[]) {
    
      boolean lineSep = false;
    
      int sLen = data == null ? 0 : data.length;
    
      (sLen == 0) return new String("");
    
      int eLen = (sLen / 3) * 3;
    
      int cCnt = (sLen - 1) / 3 + 1 << 2;
    
      int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0);
    
      char dArr[] = new char[dLen];
    
      int s = 0;
    
      int d = 0;
    
      int cc = 0;
    
      do {
    
      if(s >= eLen)
    
      break;
    
      int i = (data[s++] & 0xff) << 16 | (data[s++] & 0xff) << 8 | data[s++] & 0xff;
    
      dArr[d++] = CA[i >>> 18 & 0x3f];
    
      dArr[d++] = CA[i >>> 12 & 0x3f];
    
      dArr[d++] = CA[i >>> 6 & 0x3f];
    
      dArr[d++] = CA[i & 0x3f];
    
      if(lineSep && ++cc == 19 && d < dLen - 2)
    
      { dArr[d++] = '\r';
    
      dArr[d++] = '\n';
    
      cc = 0;
    
      }
    
      } while(true);
    
      int left = sLen - eLen;
    
      if(left > 0)
    
      { int i = (data[eLen] & 0xff) << 10 | (left != 2 ? 0 : (data[sLen - 1] & 0xff) << 2);
    
      dArr[dLen - 4] = CA[i >> 12]; dArr[dLen - 3] = CA[i >>> 6 & 0x3f];
    
      dArr[dLen - 2] = left != 2 ? '=' : CA[i & 0x3f]; dArr[dLen - 1] = '=';
    
      } return new String(dArr);
    
      }
    
      public static final String encodeHex(byte bytes[])
    
      { StringBuffer buf = new StringBuffer(bytes.length * 2);
    
      for(int i = 0; i < bytes.length; i++) {
    
      if((bytes[i] & 0xff) < 16) buf.append("0");
    
      buf.append(Long.toString(bytes[i] & 0xff, 16));
    
      }   return buf.toString();
    
      }
    
      public static final byte[] decodeHex(String hex) {
    
      char chars[] = hex.toCharArray();
    
      byte bytes[] = new byte[chars.length / 2];
    
      int byteCount = 0;
    
      for(int i = 0; i < chars.length; i += 2) {
    
      int newByte = 0;
    
      newByte |= hexCharToByte(chars[i]);
    
      newByte <<= 4;
    
      newByte |= hexCharToByte(chars[i + 1]);
    
      bytes[byteCount] = (byte)newByte; byteCount++; }   return bytes; }
    
  • 相关阅读:
    kafka 的基本概念及使用场景
    使用RedisTemplate执行Redis脚本
    SpringBoot使用Lua脚本操作Redis
    Java不定参数Object… obj 和 Object[] 的区别
    IntelliJ IDEA添加快捷键自动输入@author信息
    使用Guava RateLimiter限流以及源码解析
    go fileserver
    记录了prometheus 告警指标
    https://mp.weixin.qq.com/s/ZBsZHQtAz_vKS8fwvHKB3g图文分析Kubernetes认证、授权和准入控制
    es不停机滚动update
  • 原文地址:https://www.cnblogs.com/wen12128/p/1848061.html
Copyright © 2020-2023  润新知