Browse Source

first commit

15810770710@163.com 2 years ago
parent
commit
3184143659
49 changed files with 2105 additions and 0 deletions
  1. 2 0
      .mvn/wrapper/maven-wrapper.properties
  2. 19 0
      HELP.md
  3. BIN
      lib/dll/liblog-1.dll
  4. BIN
      lib/dll/libskf-1.dll
  5. BIN
      lib/dll/libskfsec-1.dll
  6. BIN
      lib/dll/libsm-1.dll
  7. BIN
      lib/dll/libwinpthread-1.dll
  8. BIN
      lib/dll/libx509.dll
  9. BIN
      lib/dll/libzx-1.dll
  10. BIN
      lib/dll/sk.dat
  11. 118 0
      lib/dll/skfSec.log
  12. BIN
      lib/dll/test_skfsec.exe
  13. BIN
      lib/gmjce-1.0.jar
  14. BIN
      lib/gmjsse-1.0.jar
  15. BIN
      lib/ukey-1.0.1.jar
  16. 316 0
      mvnw
  17. 188 0
      mvnw.cmd
  18. 121 0
      pom.xml
  19. 19 0
      src/main/java/com/jkcredit/identity/IdentityVerifyApplication.java
  20. 179 0
      src/main/java/com/jkcredit/identity/config/HttpClientConfiguration.java
  21. 24 0
      src/main/java/com/jkcredit/identity/config/SignConfig.java
  22. 22 0
      src/main/java/com/jkcredit/identity/config/properties/HttpClientProperties.java
  23. 16 0
      src/main/java/com/jkcredit/identity/constant/AuthConstant.java
  24. 9 0
      src/main/java/com/jkcredit/identity/constant/CommonConstants.java
  25. 26 0
      src/main/java/com/jkcredit/identity/constant/ResponseConstants.java
  26. 30 0
      src/main/java/com/jkcredit/identity/controller/IdentityInfoController.java
  27. 21 0
      src/main/java/com/jkcredit/identity/model/dto/AuthDataDTO.java
  28. 26 0
      src/main/java/com/jkcredit/identity/model/dto/IdentityInfoDTO.java
  29. 30 0
      src/main/java/com/jkcredit/identity/model/dto/IdentityPhotoInfoDTO.java
  30. 57 0
      src/main/java/com/jkcredit/identity/model/to/AuthDataTO.java
  31. 13 0
      src/main/java/com/jkcredit/identity/model/to/HandTO.java
  32. 35 0
      src/main/java/com/jkcredit/identity/model/to/LoginTO.java
  33. 18 0
      src/main/java/com/jkcredit/identity/model/to/SignBean.java
  34. 58 0
      src/main/java/com/jkcredit/identity/model/vo/ApiResponse.java
  35. 14 0
      src/main/java/com/jkcredit/identity/model/vo/AuthRepData.java
  36. 18 0
      src/main/java/com/jkcredit/identity/model/vo/AuthSignData.java
  37. 33 0
      src/main/java/com/jkcredit/identity/model/vo/CommonResponseVO.java
  38. 9 0
      src/main/java/com/jkcredit/identity/model/vo/HandVo.java
  39. 12 0
      src/main/java/com/jkcredit/identity/model/vo/TokenVo.java
  40. 22 0
      src/main/java/com/jkcredit/identity/service/IdentityVerifyService.java
  41. 227 0
      src/main/java/com/jkcredit/identity/service/Impl/IdentityVerifyServiceImpl.java
  42. 152 0
      src/main/java/com/jkcredit/identity/service/Impl/TokenServiceImpl.java
  43. 21 0
      src/main/java/com/jkcredit/identity/service/TokenService.java
  44. 23 0
      src/main/java/com/jkcredit/identity/task/TokenTask.java
  45. 116 0
      src/main/java/com/jkcredit/identity/util/DESUtil.java
  46. 26 0
      src/main/java/com/jkcredit/identity/util/TokenConCurrentHashMapUtil.java
  47. 11 0
      src/main/resources/application.yml
  48. 61 0
      src/main/resources/logback-spring.xml
  49. 13 0
      src/test/java/com/jkcredit/identity/IdentityVerifyApplicationTests.java

+ 2 - 0
.mvn/wrapper/maven-wrapper.properties

@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar

+ 19 - 0
HELP.md

@@ -0,0 +1,19 @@
+# Getting Started
+
+### Reference Documentation
+
+For further reference, please consider the following sections:
+
+* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
+* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.6.4/maven-plugin/reference/html/)
+* [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.6.4/maven-plugin/reference/html/#build-image)
+* [Spring Web](https://docs.spring.io/spring-boot/docs/2.6.4/reference/htmlsingle/#boot-features-developing-web-applications)
+
+### Guides
+
+The following guides illustrate how to use some features concretely:
+
+* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
+* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
+* [Building REST services with Spring](https://spring.io/guides/tutorials/bookmarks/)
+

BIN
lib/dll/liblog-1.dll


BIN
lib/dll/libskf-1.dll


BIN
lib/dll/libskfsec-1.dll


BIN
lib/dll/libsm-1.dll


BIN
lib/dll/libwinpthread-1.dll


BIN
lib/dll/libx509.dll


BIN
lib/dll/libzx-1.dll


BIN
lib/dll/sk.dat


+ 118 - 0
lib/dll/skfSec.log

@@ -0,0 +1,118 @@
+I[10-12 11:18:31.057 tid:16456] SKFSECAPI zxlog_init..

+
+I[10-12 11:18:31.058 tid:16456] SKFSECAPI SKF_EnumDev:skfsoftdev

+
+I[10-12 11:18:31.060 tid:16456] SKFSECAPI GenRandom succ

+
+I[10-12 11:18:31.061 tid:16456] SKFSECAPI EnumApplication succ:0

+
+I[10-12 11:18:31.061 tid:16456] SKFSECAPI EnumApplication succ:vfApp,vfApp,7

+
+I[10-12 11:18:31.082 tid:16456] SKFSECAPI SKF_ExportCertificate updateSign succ:0

+
+I[10-12 11:18:31.191 tid:16456] SKFSECAPI SKF_ExportCertificate sign succ:0

+
+I[10-12 11:18:31.313 tid:16456] SKFSECAPI SKF_ExportCertificate enc succ:0

+
+I[10-12 11:18:31.424 tid:16456] SKFSECAPI SKF_ExportCertificate readSkfFile succ:0

+I[10-12 11:34:30.317 tid:12020] SKFSECAPI zxlog_init..

+
+I[10-12 11:34:30.318 tid:12020] SKFSECAPI SKF_EnumDev:skfsoftdev

+
+I[10-12 11:34:30.320 tid:12020] SKFSECAPI GenRandom succ

+
+I[10-12 11:34:30.320 tid:12020] SKFSECAPI EnumApplication succ:0

+
+I[10-12 11:34:30.321 tid:12020] SKFSECAPI EnumApplication succ:vfApp,vfApp,7

+
+I[10-12 11:34:30.335 tid:12020] SKFSECAPI SKF_ExportCertificate updateSign succ:0

+
+I[10-13 07:50:45.379 tid:13833] SKFSECAPI zxlog_init..

+
+I[10-13 07:50:45.379 tid:13833] SKFSECAPI SKF_EnumDev:skfsoftdev

+
+I[10-13 07:50:45.441 tid:13833] SKFSECAPI GenRandom succ

+
+I[10-13 07:50:45.441 tid:13833] SKFSECAPI EnumApplication succ:0

+
+I[10-13 07:50:45.441 tid:13833] SKFSECAPI EnumApplication succ:vfApp,vfApp,7

+
+I[10-13 07:50:45.457 tid:13833] SKFSECAPI SKF_ExportCertificate updateSign succ:0

+
+I[10-13 07:50:45.551 tid:13833] SKFSECAPI SKF_ExportCertificate sign succ:0

+
+I[10-13 07:50:45.660 tid:13833] SKFSECAPI SKF_ExportCertificate enc succ:0

+
+I[10-13 07:50:45.754 tid:13833] SKFSECAPI SKF_ExportCertificate readSkfFile succ:0

+
+I[10-13 11:45:52.734 tid:66820] SKFSECAPI zxlog_init..

+
+I[10-13 11:45:52.734 tid:66820] SKFSECAPI SKF_EnumDev:skfsoftdev

+
+I[10-13 11:45:52.744 tid:66820] SKFSECAPI GenRandom succ

+
+I[10-13 11:45:52.744 tid:66820] SKFSECAPI EnumApplication succ:0

+
+I[10-13 11:45:52.744 tid:66820] SKFSECAPI EnumApplication succ:vfApp,vfApp,7

+
+I[10-13 11:45:52.755 tid:66820] SKFSECAPI SKF_ExportCertificate updateSign succ:0

+
+I[10-13 11:45:52.860 tid:66820] SKFSECAPI SKF_ExportCertificate sign succ:0

+
+I[10-13 11:45:52.977 tid:66820] SKFSECAPI SKF_ExportCertificate enc succ:0

+
+I[10-13 11:45:53.088 tid:66820] SKFSECAPI SKF_ExportCertificate readSkfFile succ:0

+
+I[10-13 11:45:53.231 tid:66820] SKFSECAPI SKF_ExportCertificate readSkfFile succ:0

+I[10-13 15:27:11.348 tid:13726] SKFSECAPI zxlog_init..

+
+I[10-13 15:27:11.348 tid:13726] SKFSECAPI SKF_EnumDev:skfsoftdev

+
+I[10-13 15:28:37.935 tid:88932] SKFSECAPI zxlog_init..

+
+I[10-13 15:28:37.941 tid:88932] SKFSECAPI GenRandom succ

+
+I[10-13 15:28:37.942 tid:88932] SKFSECAPI EnumApplication succ:0

+
+I[10-13 15:28:37.942 tid:88932] SKFSECAPI EnumApplication succ:vfApp,vfApp,7

+
+I[10-13 15:28:37.962 tid:88932] SKFSECAPI SKF_ExportCertificate sign succ:0

+
+I[10-13 15:28:37.967 tid:88932] SKFSECAPI SKF_ExportCertificate enc succ:0

+
+I[10-13 16:17:48.130 tid:10109] SKFSECAPI zxlog_init..

+
+I[10-13 16:21:40.575 tid:15443] SKFSECAPI zxlog_init..

+
+I[10-13 16:23:28.801 tid:87916] SKFSECAPI zxlog_init..

+
+I[10-13 16:28:20.770 tid:19672] SKFSECAPI zxlog_init..

+
+I[10-13 16:29:02.557 tid:14532] SKFSECAPI zxlog_init..

+
+I[10-13 16:30:07.027 tid:88664] SKFSECAPI zxlog_init..

+
+I[10-13 16:31:04.919 tid:14262] SKFSECAPI zxlog_init..

+
+I[10-13 16:31:04.969 tid:14262] SKFSECAPI GenRandom succ

+
+I[10-13 16:31:04.970 tid:14262] SKFSECAPI EnumApplication succ:0

+
+I[10-13 16:31:04.970 tid:14262] SKFSECAPI EnumApplication succ:vfApp,vfApp,7

+
+I[10-13 16:31:04.992 tid:14262] SKFSECAPI SKF_ExportCertificate sign succ:0

+
+I[10-13 16:31:04.997 tid:14262] SKFSECAPI SKF_ExportCertificate enc succ:0

+
+I[10-13 16:51:19.967 tid:54824] SKFSECAPI zxlog_init..

+
+I[10-13 16:51:19.972 tid:54824] SKFSECAPI GenRandom succ

+
+I[10-13 16:51:19.972 tid:54824] SKFSECAPI EnumApplication succ:0

+
+I[10-13 16:51:19.973 tid:54824] SKFSECAPI EnumApplication succ:vfApp,vfApp,7

+
+I[10-13 16:51:19.994 tid:54824] SKFSECAPI SKF_ExportCertificate sign succ:0

+
+I[10-13 16:51:19.999 tid:54824] SKFSECAPI SKF_ExportCertificate enc succ:0

+

BIN
lib/dll/test_skfsec.exe


BIN
lib/gmjce-1.0.jar


BIN
lib/gmjsse-1.0.jar


BIN
lib/ukey-1.0.1.jar


+ 316 - 0
mvnw

@@ -0,0 +1,316 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#    https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+#   JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+#   M2_HOME - location of maven2's installed home dir
+#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
+#     e.g. to debug Maven itself, use
+#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+  if [ -f /usr/local/etc/mavenrc ] ; then
+    . /usr/local/etc/mavenrc
+  fi
+
+  if [ -f /etc/mavenrc ] ; then
+    . /etc/mavenrc
+  fi
+
+  if [ -f "$HOME/.mavenrc" ] ; then
+    . "$HOME/.mavenrc"
+  fi
+
+fi
+
+# OS specific support.  $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+  CYGWIN*) cygwin=true ;;
+  MINGW*) mingw=true;;
+  Darwin*) darwin=true
+    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+    if [ -z "$JAVA_HOME" ]; then
+      if [ -x "/usr/libexec/java_home" ]; then
+        export JAVA_HOME="`/usr/libexec/java_home`"
+      else
+        export JAVA_HOME="/Library/Java/Home"
+      fi
+    fi
+    ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+  if [ -r /etc/gentoo-release ] ; then
+    JAVA_HOME=`java-config --jre-home`
+  fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+  ## resolve links - $0 may be a link to maven's home
+  PRG="$0"
+
+  # need this for relative symlinks
+  while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+      PRG="$link"
+    else
+      PRG="`dirname "$PRG"`/$link"
+    fi
+  done
+
+  saveddir=`pwd`
+
+  M2_HOME=`dirname "$PRG"`/..
+
+  # make it fully qualified
+  M2_HOME=`cd "$M2_HOME" && pwd`
+
+  cd "$saveddir"
+  # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --unix "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME="`(cd "$M2_HOME"; pwd)`"
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+  javaExecutable="`which javac`"
+  if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+    # readlink(1) is not available as standard on Solaris 10.
+    readLink=`which readlink`
+    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+      if $darwin ; then
+        javaHome="`dirname \"$javaExecutable\"`"
+        javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+      else
+        javaExecutable="`readlink -f \"$javaExecutable\"`"
+      fi
+      javaHome="`dirname \"$javaExecutable\"`"
+      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+      JAVA_HOME="$javaHome"
+      export JAVA_HOME
+    fi
+  fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+  if [ -n "$JAVA_HOME"  ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+      # IBM's JDK on AIX uses strange locations for the executables
+      JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+      JAVACMD="$JAVA_HOME/bin/java"
+    fi
+  else
+    JAVACMD="`\\unset -f command; \\command -v java`"
+  fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+  echo "Error: JAVA_HOME is not defined correctly." >&2
+  echo "  We cannot execute $JAVACMD" >&2
+  exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+  echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+  if [ -z "$1" ]
+  then
+    echo "Path not specified to find_maven_basedir"
+    return 1
+  fi
+
+  basedir="$1"
+  wdir="$1"
+  while [ "$wdir" != '/' ] ; do
+    if [ -d "$wdir"/.mvn ] ; then
+      basedir=$wdir
+      break
+    fi
+    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+    if [ -d "${wdir}" ]; then
+      wdir=`cd "$wdir/.."; pwd`
+    fi
+    # end of workaround
+  done
+  echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+  if [ -f "$1" ]; then
+    echo "$(tr -s '\n' ' ' < "$1")"
+  fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+  exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Found .mvn/wrapper/maven-wrapper.jar"
+    fi
+else
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+    fi
+    if [ -n "$MVNW_REPOURL" ]; then
+      jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+    else
+      jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+    fi
+    while IFS="=" read key value; do
+      case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+      esac
+    done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Downloading from: $jarUrl"
+    fi
+    wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+    if $cygwin; then
+      wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+    fi
+
+    if command -v wget > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found wget ... using wget"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+        else
+            wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+        fi
+    elif command -v curl > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found curl ... using curl"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            curl -o "$wrapperJarPath" "$jarUrl" -f
+        else
+            curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+        fi
+
+    else
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Falling back to using Java to download"
+        fi
+        javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+        # For Cygwin, switch paths to Windows format before running javac
+        if $cygwin; then
+          javaClass=`cygpath --path --windows "$javaClass"`
+        fi
+        if [ -e "$javaClass" ]; then
+            if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Compiling MavenWrapperDownloader.java ..."
+                fi
+                # Compiling the Java class
+                ("$JAVA_HOME/bin/javac" "$javaClass")
+            fi
+            if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                # Running the downloader
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Running MavenWrapperDownloader.java ..."
+                fi
+                ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+            fi
+        fi
+    fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+  echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --path --windows "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+    MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+  $MAVEN_OPTS \
+  $MAVEN_DEBUG_OPTS \
+  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+  "-Dmaven.home=${M2_HOME}" \
+  "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

+ 188 - 0
mvnw.cmd

@@ -0,0 +1,188 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements.  See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership.  The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License.  You may obtain a copy of the License at
+@REM
+@REM    https://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied.  See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM     e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+    IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Found %WRAPPER_JAR%
+    )
+) else (
+    if not "%MVNW_REPOURL%" == "" (
+        SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+    )
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Couldn't find %WRAPPER_JAR%, downloading it ...
+        echo Downloading from: %DOWNLOAD_URL%
+    )
+
+    powershell -Command "&{"^
+		"$webclient = new-object System.Net.WebClient;"^
+		"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+		"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+		"}"^
+		"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+		"}"
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Finished downloading %WRAPPER_JAR%
+    )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% ^
+  %JVM_CONFIG_MAVEN_PROPS% ^
+  %MAVEN_OPTS% ^
+  %MAVEN_DEBUG_OPTS% ^
+  -classpath %WRAPPER_JAR% ^
+  "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
+  %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%"=="on" pause
+
+if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
+
+cmd /C exit /B %ERROR_CODE%

+ 121 - 0
pom.xml

@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.6.4</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+    <groupId>com.jkcredit</groupId>
+    <artifactId>identity-verify</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>identity-verify</name>
+    <description>identity-verify</description>
+    <properties>
+        <java.version>1.8</java.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <version>2.3.7.RELEASE</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.7.16</version>
+        </dependency>
+
+        <dependency>
+            <groupId>net.java.dev.jna</groupId>
+            <artifactId>jna</artifactId>
+            <version>4.5.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.zdab</groupId>
+            <artifactId>ukey</artifactId>
+            <version>1.0.1</version>
+            <scope>system</scope>
+            <systemPath>${project.basedir}/lib/ukey-1.0.1.jar</systemPath>
+        </dependency>
+
+        <dependency>
+            <groupId>com.zdab</groupId>
+            <artifactId>gmjce</artifactId>
+            <version>1.0</version>
+            <scope>system</scope>
+            <systemPath>${project.basedir}/lib/gmjce-1.0.jar</systemPath>
+        </dependency>
+
+        <dependency>
+            <groupId>com.zdab</groupId>
+            <artifactId>gmjsse</artifactId>
+            <version>1.0</version>
+            <scope>system</scope>
+            <systemPath>${project.basedir}/lib/gmjsse-1.0.jar</systemPath>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.76</version>
+        </dependency>
+        <dependency>
+            <groupId>org.quartz-scheduler</groupId>
+            <artifactId>quartz</artifactId>
+            <version>2.3.0</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.6.4</version>
+                <configuration>
+                    <includeSystemScope>true</includeSystemScope>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>copy-dependencies</id>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 19 - 0
src/main/java/com/jkcredit/identity/IdentityVerifyApplication.java

@@ -0,0 +1,19 @@
+package com.jkcredit.identity;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@SpringBootApplication
+@EnableScheduling
+public class IdentityVerifyApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(IdentityVerifyApplication.class, args);
+    }
+
+}

+ 179 - 0
src/main/java/com/jkcredit/identity/config/HttpClientConfiguration.java

@@ -0,0 +1,179 @@
+package com.jkcredit.identity.config;
+
+import com.jkcredit.identity.config.properties.HttpClientProperties;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HeaderElement;
+import org.apache.http.HeaderElementIterator;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.ConnectionKeepAliveStrategy;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.message.BasicHeaderElementIterator;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.ssl.SSLContexts;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.ClientHttpRequestFactory;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.scheduling.TaskScheduler;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+import org.springframework.web.client.RestTemplate;
+
+import javax.net.ssl.SSLContext;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Security;
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 国密Https客户端
+ *
+ * 同时支持HTTP和HTTPS
+ * 使用连接池重复使用连接并节省创建连接的开销
+ * 启动空闲连接监视器以持续清理过时的连接
+ */
+@Slf4j
+@Configuration
+public class HttpClientConfiguration {
+    final CloseableHttpClient httpClient;
+
+    public HttpClientConfiguration(CloseableHttpClient httpClient) {
+        this.httpClient = httpClient;
+    }
+
+    @Bean
+    public HttpComponentsClientHttpRequestFactory clientHttpRequestFactory() {
+        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
+        clientHttpRequestFactory.setHttpClient(httpClient);
+        return clientHttpRequestFactory;
+    }
+
+    @Bean
+    public TaskScheduler taskScheduler() {
+        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
+        scheduler.setThreadNamePrefix("poolScheduler");
+        scheduler.setPoolSize(50);
+        return scheduler;
+    }
+    @Bean
+    public RestTemplate gmRestTemplate(ClientHttpRequestFactory factory) {
+        RestTemplate restTemplate = new RestTemplate();
+        restTemplate.setRequestFactory(factory);
+        restTemplate.setInterceptors(Collections.singletonList((request, body, execution) -> {
+            // log the http request
+            log.info("URI: {}", request.getURI());
+            log.info("HTTP Method: {}", request.getMethodValue());
+            log.info("HTTP Headers: {}", request.getHeaders());
+            return execution.execute(request, body);
+        }));
+        return restTemplate;
+    }
+
+
+    @Slf4j
+    @EnableScheduling
+    @Configuration
+    @EnableConfigurationProperties(HttpClientProperties.class)
+    public static class HttpClientConfig {
+
+        private final HttpClientProperties httpClientProperties;
+
+        public HttpClientConfig(HttpClientProperties httpClientProperties) {
+            this.httpClientProperties = httpClientProperties;
+        }
+
+        @Bean
+        public PoolingHttpClientConnectionManager poolingConnectionManager() {
+            Security.insertProviderAt(new cn.gmssl.jce.provider.GMJCE(), 1);
+            Security.insertProviderAt(new cn.gmssl.jsse.provider.GMJSSE(), 2);
+
+            SSLConnectionSocketFactory sslsf = null;
+
+            try {
+                TrustStrategy acceptingTrustStrategy = (x509Certificates, authType) -> true;
+                SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
+                sslsf = new SSLConnectionSocketFactory(sslContext,
+                        new String[]{"GMSSLv1.1"}, new String[]{"ECC_SM4_SM3"},
+                        new NoopHostnameVerifier());
+            } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
+                log.error("连接池管理器初始化失败,原因是 " + e.getMessage(), e);
+                throw new RuntimeException();
+            }
+
+            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
+                    .<ConnectionSocketFactory>create().register("https", sslsf)
+                    .register("http", new PlainConnectionSocketFactory())
+                    .build();
+
+            PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
+            poolingConnectionManager.setMaxTotal(httpClientProperties.getMaxTotalConnections());
+            return poolingConnectionManager;
+        }
+
+        @Bean
+        public ConnectionKeepAliveStrategy connectionKeepAliveStrategy() {
+            return (response, context) -> {
+                HeaderElementIterator it = new BasicHeaderElementIterator
+                        (response.headerIterator(HTTP.CONN_KEEP_ALIVE));
+                while (it.hasNext()) {
+                    HeaderElement he = it.nextElement();
+                    String param = he.getName();
+                    String value = he.getValue();
+
+                    if (value != null && param.equalsIgnoreCase("timeout")) {
+                        return Long.parseLong(value) * 1000;
+                    }
+                }
+                return httpClientProperties.getDefaultKeepAliveTimeMillis();
+            };
+        }
+
+        @Bean
+        public CloseableHttpClient httpClient() {
+            RequestConfig requestConfig = RequestConfig.custom()
+                    .setConnectionRequestTimeout(httpClientProperties.getRequestTimeout())
+                    .setConnectTimeout(httpClientProperties.getConnectTimeout())
+                    .setSocketTimeout(httpClientProperties.getSocketTimeout()).build();
+
+            return HttpClients.custom()
+                    .setDefaultRequestConfig(requestConfig)
+                    .setConnectionManager(poolingConnectionManager())
+                    .setKeepAliveStrategy(connectionKeepAliveStrategy())
+                    .build();
+        }
+
+        @Bean
+        public Runnable idleConnectionMonitor(final PoolingHttpClientConnectionManager connectionManager) {
+            return new Runnable() {
+                @Override
+                @Scheduled(fixedDelay = 10000)
+                public void run() {
+                    try {
+                        if (connectionManager != null) {
+                            log.trace("运行IdleConnectionMonitor-关闭过期和空闲连接...");
+                            connectionManager.closeExpiredConnections();
+                            connectionManager.closeIdleConnections(httpClientProperties.getCloseIdleConnectionWaitTimeSecs(), TimeUnit.SECONDS);
+                        } else {
+                            log.trace("运行IdleConnectionMonitor-未初始化Http客户端连接管理器");
+                        }
+                    } catch (Exception e) {
+                        log.error("运行IdleConnectionMonitor-发生异常. msg={}, e={}", e.getMessage(), e);
+                    }
+                }
+            };
+        }
+    }
+}

+ 24 - 0
src/main/java/com/jkcredit/identity/config/SignConfig.java

@@ -0,0 +1,24 @@
+package com.jkcredit.identity.config;
+
+import com.zdab.ukey.service.UKeyService;
+import com.zdab.ukey.service.impl.UKeyServiceImpl;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@Configuration
+public class SignConfig {
+    @Bean
+    public UKeyService ukeyService() {
+        return UKeyServiceImpl.getINSTANCE();
+    }
+
+//    @Bean
+//    public RestTemplate restTemplate() {
+//        return new RestTemplate();
+//    }
+
+}

+ 22 - 0
src/main/java/com/jkcredit/identity/config/properties/HttpClientProperties.java

@@ -0,0 +1,22 @@
+package com.jkcredit.identity.config.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@Data
+@ConfigurationProperties(prefix = "ab.http")
+public class HttpClientProperties {
+
+    // Determines the timeout in milliseconds until a connection is established.
+    private int connectTimeout = 30000;
+
+    // The timeout when requesting a connection from the connection manager.
+    private int requestTimeout = 30000;
+
+    // The timeout for waiting for data
+    private int socketTimeout = 60000;
+
+    private int maxTotalConnections = 50;
+    private int defaultKeepAliveTimeMillis = 20 * 1000;
+    private int closeIdleConnectionWaitTimeSecs = 30;
+}

+ 16 - 0
src/main/java/com/jkcredit/identity/constant/AuthConstant.java

@@ -0,0 +1,16 @@
+package com.jkcredit.identity.constant;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+public class AuthConstant {
+    public final static String SERVER_CERT = "MIIBxjCCAWygAwIBAgIHEVCvOCAIADAKBggqgRzPVQGDdTBCMQswCQYDVQQGDAJDTjEM" +
+            "MAoGA1UECgwDRFRUMQwwCgYDVQQLDANETVQxFzAVBgNVBAMMDkluZGl2aWR1YWxSb290MB4XDTIwMDQwODAwNTUwMFoXDTI1MDQwO" +
+            "DAwNTUwMFowKzELMAkGA1UEBgwCQ04xDDAKBgNVBAoMA0RUVDEOMAwGA1UEAwwFY29uXzEwWTATBgcqhkjOPQIBBggqgRzPVQGCLQ" +
+            "NCAASXqoz0/rclBgre5hAQVqEl76VEbGygv0cFmJ+GU3CITAHeEW/8PSkTgB9zzoAJORQvRGTWrsVd0YGO+Thid7vmo2QwYjALBgN" +
+            "VHQ8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHwYDVR0jBBgwFoAUZPl6WchLvLbWWqnYAvN4dFSh3fAwHQYDVR0OBBYEFL2+" +
+            "gx+k491uciI/0Kb2ayc96OAQMAoGCCqBHM9VAYN1A0gAMEUCIQDvLTHeVCrkomVWXAxKVM/Cfti3rOJjBJ12SPmpljtm8gIgX6rMs" +
+            "kHl3Rktn+JwSA8A3tWqotoOslJLIfwAXHfO+uw=";
+
+}

+ 9 - 0
src/main/java/com/jkcredit/identity/constant/CommonConstants.java

@@ -0,0 +1,9 @@
+package com.jkcredit.identity.constant;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+public class CommonConstants {
+    public static final String TOKEN_KEY = "token";
+}

+ 26 - 0
src/main/java/com/jkcredit/identity/constant/ResponseConstants.java

@@ -0,0 +1,26 @@
+package com.jkcredit.identity.constant;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+public class ResponseConstants {
+    public static final String RESPONSE_CODE_SUCCESS = "0";
+
+    public static final String RESPONSE_CODE_FAILED = "1";
+
+    public static final String RESPONSE_RESULT_FAILED = "false";
+
+    public static final String RESPONSE_MESSAGE_ERROR_EX_KEY = "exKey必须16位字节编码的base64!";
+
+    public static final String RESPONSE_MESSAGE_ERROR_SIGN = "服务端返回数据验签失败";
+
+    public static final String RESPONSE_MESSAGE_SUCCESS = "查询成功";
+
+    public static final String RESPONSE_MESSAGE_REQUEST_FAILED = "查询失败";
+
+    public static final String RESPONSE_MESSAGE_JSON_PARSE_FAILED = "json转换失败";
+
+    public static final String RESPONSE_MESSAGE_DECRYPT_FAILED = "参数解密失败";
+
+}

+ 30 - 0
src/main/java/com/jkcredit/identity/controller/IdentityInfoController.java

@@ -0,0 +1,30 @@
+package com.jkcredit.identity.controller;
+
+import com.jkcredit.identity.model.vo.CommonResponseVO;
+import com.jkcredit.identity.service.IdentityVerifyService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@RestController
+@Slf4j
+public class IdentityInfoController {
+    @Autowired
+    IdentityVerifyService identityVerifyService;
+
+    @PostMapping("/api/identityInfo")
+    public CommonResponseVO identityInfoQuery(@RequestBody String params) {
+        return identityVerifyService.validateIdentityInfo(params);
+    }
+
+    @PostMapping("/api/identityPhotoInfo")
+    public CommonResponseVO identityPhotoInfoQuery(@RequestBody String params) {
+        return identityVerifyService.validatePhotoIdentityInfo(params);
+    }
+}

+ 21 - 0
src/main/java/com/jkcredit/identity/model/dto/AuthDataDTO.java

@@ -0,0 +1,21 @@
+package com.jkcredit.identity.model.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+public class AuthDataDTO {
+
+    @NotBlank(message = "参数中缺少姓名")
+    private String name;
+
+    @NotBlank(message = "参数中缺少身份证")
+    private String idCard;
+
+    @NotBlank(message = "参数中缺少认证模式")
+    private String authMode;
+
+    private String photoData;
+
+}

+ 26 - 0
src/main/java/com/jkcredit/identity/model/dto/IdentityInfoDTO.java

@@ -0,0 +1,26 @@
+package com.jkcredit.identity.model.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@Data
+public class IdentityInfoDTO implements Serializable {
+    private static final long serialVersionUID = -5610932544817685237L;
+    /**
+     * 姓名
+     */
+    private String name;
+    /**
+     * 身份证号
+     */
+    private String idCode;
+    /**
+     * 流水号
+     */
+    private String requestId;
+}

+ 30 - 0
src/main/java/com/jkcredit/identity/model/dto/IdentityPhotoInfoDTO.java

@@ -0,0 +1,30 @@
+package com.jkcredit.identity.model.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@Data
+public class IdentityPhotoInfoDTO implements Serializable {
+    private static final long serialVersionUID = -5610932544817685237L;
+    /**
+     * 姓名
+     */
+    private String name;
+    /**
+     * 身份证号
+     */
+    private String idCode;
+    /**
+     * 照片base64
+     */
+    private String photo;
+    /**
+     * 流水号
+     */
+    private String requestId;
+}

+ 57 - 0
src/main/java/com/jkcredit/identity/model/to/AuthDataTO.java

@@ -0,0 +1,57 @@
+package com.jkcredit.identity.model.to;
+
+import lombok.Data;
+
+public class AuthDataTO extends SignBean<AuthDataTO.BizData> {
+
+    @Data
+    public static class BizData {
+
+        private String timeStamp;
+
+        /**
+         * 认证模式
+         */
+        private String authMode;
+
+
+        /**
+         * 认证数据
+         */
+        private String authData;
+
+        @Data
+        public static class AuthData {
+
+            /**
+             * 应用名
+             */
+            private String appName;
+
+            /**
+             * 姓名
+             */
+            private String name;
+
+            /**
+             * 身份证
+             */
+            private String idCard;
+
+            /**
+             * 身份证有效期起始日期
+             */
+            private String yXQQSRQ;
+
+            /**
+             * 身份证有效期截止日期
+             */
+            private String yXQJZRQ;
+
+            /**
+             * 照片
+             */
+            private String photoData;
+        }
+    }
+}

+ 13 - 0
src/main/java/com/jkcredit/identity/model/to/HandTO.java

@@ -0,0 +1,13 @@
+package com.jkcredit.identity.model.to;
+
+import lombok.Data;
+
+@Data
+public class HandTO {
+
+    /**
+     * 时间戳
+     */
+    private String timeStamp;
+}
+

+ 35 - 0
src/main/java/com/jkcredit/identity/model/to/LoginTO.java

@@ -0,0 +1,35 @@
+package com.jkcredit.identity.model.to;
+
+import lombok.Data;
+
+public class LoginTO extends SignBean<LoginTO.BizData> {
+
+    @Data
+    public static class BizData {
+
+        /**
+         * 用户名
+         */
+        private String username;
+
+        /**
+         * 密码或刷新token
+         */
+        private String credentials;
+
+        /**
+         * 时间戳
+         */
+        private String timeStamp;
+
+        /**
+         * 服务器随机数
+         */
+        private String r1;
+
+        /**
+         * 客户端随机数
+         */
+        private String r2;
+    }
+}

+ 18 - 0
src/main/java/com/jkcredit/identity/model/to/SignBean.java

@@ -0,0 +1,18 @@
+package com.jkcredit.identity.model.to;
+
+import lombok.Data;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+@Data
+public class SignBean<T> {
+
+    @NotBlank(message = "数据包中缺少签名")
+    protected String sign;
+
+    @Valid
+    @NotNull(message = "数据包中缺少认证数据")
+    protected T bizData;
+}

+ 58 - 0
src/main/java/com/jkcredit/identity/model/vo/ApiResponse.java

@@ -0,0 +1,58 @@
+package com.jkcredit.identity.model.vo;
+
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * 响应信息主体
+ *
+ * @param <T>
+ * @author cislc
+ */
+@ToString
+@NoArgsConstructor
+@AllArgsConstructor
+@Accessors(chain = true)
+public class ApiResponse<T> implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	@Getter
+	@Setter
+	private int code = 9999;
+
+	@Getter
+	@Setter
+	private String msg;
+
+
+	@Getter
+	@Setter
+	private T data;
+
+	public static <T> ApiResponse<T> ok() {
+		return restResult(null, 0, null);
+	}
+
+	public static <T> ApiResponse<T> ok(T data) {
+		return restResult(data, 0, "success");
+	}
+
+	public static <T> ApiResponse<T> failed() {
+		return restResult(null, 1, "failed");
+	}
+
+	public static <T> ApiResponse<T> failed(int code ,String msg) {
+		return restResult(null, code, msg);
+	}
+
+
+	private static <T> ApiResponse<T> restResult(T data, int code, String msg) {
+		ApiResponse<T> apiResult = new ApiResponse<>();
+		apiResult.setCode(code);
+		apiResult.setData(data);
+		apiResult.setMsg(msg);
+		return apiResult;
+	}
+}

+ 14 - 0
src/main/java/com/jkcredit/identity/model/vo/AuthRepData.java

@@ -0,0 +1,14 @@
+package com.jkcredit.identity.model.vo;
+
+import com.jkcredit.identity.model.to.SignBean;
+import lombok.Data;
+
+public class AuthRepData extends SignBean<AuthRepData.BizData> {
+
+    @Data
+    public static class BizData {
+
+
+        private boolean authResult;
+    }
+}

+ 18 - 0
src/main/java/com/jkcredit/identity/model/vo/AuthSignData.java

@@ -0,0 +1,18 @@
+package com.jkcredit.identity.model.vo;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class AuthSignData extends AuthRepData.BizData{
+
+    private String timeStamp;
+
+    private String username;
+
+    private String name;
+
+    private String idCard;
+
+}

+ 33 - 0
src/main/java/com/jkcredit/identity/model/vo/CommonResponseVO.java

@@ -0,0 +1,33 @@
+package com.jkcredit.identity.model.vo;
+
+import com.jkcredit.identity.constant.ResponseConstants;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class CommonResponseVO implements Serializable {
+    private static final long serialVersionUID = 8535768355630673724L;
+
+    private String code;
+
+    private String result;
+
+    private String message;
+
+    public CommonResponseVO success(String result, String message) {
+        return new CommonResponseVO(ResponseConstants.RESPONSE_CODE_SUCCESS, result, message);
+    }
+
+    public CommonResponseVO failed(String result, String message) {
+        return new CommonResponseVO(ResponseConstants.RESPONSE_CODE_FAILED, result, message);
+    }
+}

+ 9 - 0
src/main/java/com/jkcredit/identity/model/vo/HandVo.java

@@ -0,0 +1,9 @@
+package com.jkcredit.identity.model.vo;
+
+import lombok.Data;
+
+@Data
+public class HandVo {
+
+    private String svrRandom;
+}

+ 12 - 0
src/main/java/com/jkcredit/identity/model/vo/TokenVo.java

@@ -0,0 +1,12 @@
+package com.jkcredit.identity.model.vo;
+
+import lombok.Data;
+
+@Data
+public class TokenVo {
+
+    private String username;
+    private String token;
+    private String refreshToken;
+    private String encKey;
+}

+ 22 - 0
src/main/java/com/jkcredit/identity/service/IdentityVerifyService.java

@@ -0,0 +1,22 @@
+package com.jkcredit.identity.service;
+
+import com.jkcredit.identity.model.vo.CommonResponseVO;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+public interface IdentityVerifyService {
+    /**
+     * 身份证二要素
+     * @param params 姓名,身份证号
+     */
+    CommonResponseVO validateIdentityInfo(String params);
+
+    /**
+     * 身份证+人像
+     * @param params 姓名,身份证号,照片
+     */
+    CommonResponseVO validatePhotoIdentityInfo(String params);
+
+}

+ 227 - 0
src/main/java/com/jkcredit/identity/service/Impl/IdentityVerifyServiceImpl.java

@@ -0,0 +1,227 @@
+package com.jkcredit.identity.service.Impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.jkcredit.identity.constant.AuthConstant;
+import com.jkcredit.identity.constant.ResponseConstants;
+import com.jkcredit.identity.model.dto.AuthDataDTO;
+import com.jkcredit.identity.model.dto.IdentityInfoDTO;
+import com.jkcredit.identity.model.dto.IdentityPhotoInfoDTO;
+import com.jkcredit.identity.model.to.AuthDataTO;
+import com.jkcredit.identity.model.vo.*;
+import com.jkcredit.identity.service.IdentityVerifyService;
+import com.jkcredit.identity.service.TokenService;
+import com.jkcredit.identity.util.DESUtil;
+import com.zdab.ukey.service.UKeyService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.PostConstruct;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Base64;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@Service
+@Slf4j
+public class IdentityVerifyServiceImpl implements IdentityVerifyService {
+    @Value("${rz.info.username}")
+    String username;
+    @Value("${rz.info.password}")
+    String password;
+    @Value("${rz.info.url}")
+    String url;
+    @Value("${rz.info.authMode-0x40}")
+    String authMode40;
+    @Value("${rz.info.authMode-0x42}")
+    String authMode42;
+    @Value("${aes.secret}")
+    String secret;
+
+    private static String rzUrl;
+    private static byte[] serverPubKey;
+    @Autowired
+    private UKeyService uKeyService;
+    @Autowired
+    private RestTemplate restTemplate;
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    @Autowired
+    TokenService tokenService;
+
+    /**
+     * 初始化方法
+     */
+    @PostConstruct
+    public void init() {
+        serverPubKey = uKeyService.getCertPubKey(Base64.getDecoder().decode(AuthConstant.SERVER_CERT)); // 证书中提取公钥
+        rzUrl = url + "/ab/rzfw";
+    }
+
+    @Override
+    public CommonResponseVO validateIdentityInfo(String params) {
+        JSONObject requestParam = JSON.parseObject(params);
+        String decryptParams;
+        if (requestParam.get("params") != null) {
+            decryptParams = DESUtil.decrypt(requestParam.getString("params"), secret);
+        } else {
+            return new CommonResponseVO().failed(ResponseConstants.RESPONSE_RESULT_FAILED,
+                    ResponseConstants.RESPONSE_MESSAGE_DECRYPT_FAILED);
+        }
+        IdentityInfoDTO identityInfoDTO = JSON.toJavaObject(JSON.parseObject(decryptParams), IdentityInfoDTO.class);
+        TokenVo tokenVo = tokenService.getToken();
+        String token = tokenVo.getToken();
+        String encKey = tokenVo.getEncKey();
+        AuthDataDTO authDataDto = new AuthDataDTO();
+        authDataDto.setName(identityInfoDTO.getName());
+        authDataDto.setIdCard(identityInfoDTO.getIdCode());
+        authDataDto.setAuthMode(authMode40);
+
+        CommonResponseVO responseVO = rzAuth(authDataDto, token, encKey);
+        log.info("name:{}, idCode:{}, requestId:{} mode:{}, result:{}", identityInfoDTO.getName(),
+                identityInfoDTO.getIdCode(), identityInfoDTO.getRequestId(),
+                authMode40, JSON.toJSONString(responseVO));
+        return responseVO;
+    }
+
+    @Override
+    public CommonResponseVO validatePhotoIdentityInfo(String params) {
+        JSONObject requestParam = JSON.parseObject(params);
+        String decryptParams;
+        if (requestParam.get("params") != null) {
+            decryptParams = DESUtil.decrypt(requestParam.getString("params"), secret);
+        } else {
+            return new CommonResponseVO().failed(ResponseConstants.RESPONSE_RESULT_FAILED,
+                    ResponseConstants.RESPONSE_MESSAGE_DECRYPT_FAILED);
+        }
+        IdentityPhotoInfoDTO identityInfoDTO = JSON.toJavaObject(JSON.parseObject(decryptParams), IdentityPhotoInfoDTO.class);
+        TokenVo tokenVo = tokenService.getToken();
+        String token = tokenVo.getToken();
+        String encKey = tokenVo.getEncKey();
+        AuthDataDTO authDataDto = new AuthDataDTO();
+        authDataDto.setName(identityInfoDTO.getName());
+        authDataDto.setIdCard(identityInfoDTO.getIdCode());
+        authDataDto.setAuthMode(authMode42);
+        authDataDto.setPhotoData(identityInfoDTO.getPhoto());
+
+        CommonResponseVO responseVO = rzAuth(authDataDto, token, encKey);
+        log.info("name:{}, idCode:{}, requestId:{} mode:{}, result:{}", identityInfoDTO.getName(),
+                identityInfoDTO.getIdCode(), identityInfoDTO.getRequestId(),
+                authMode42, JSON.toJSONString(responseVO));
+        return responseVO;
+    }
+
+    public CommonResponseVO rzAuth(AuthDataDTO authDataDto, String token, String encKey) {
+        log.info("**人证服务**");
+        String name = authDataDto.getName();
+        String idCard = authDataDto.getIdCard();
+        String authMode = authDataDto.getAuthMode();
+        String photoData = authDataDto.getPhotoData();
+
+        byte[] keyBytes = Base64.getDecoder().decode(encKey);
+        if (keyBytes.length != 16) {
+            return new CommonResponseVO().failed(ResponseConstants.RESPONSE_RESULT_FAILED,
+                    ResponseConstants.RESPONSE_MESSAGE_ERROR_EX_KEY);
+        }
+
+        AuthDataTO.BizData.AuthData authData = new AuthDataTO.BizData.AuthData();
+        authData.setName(name);
+        authData.setIdCard(idCard);
+        if (authMode42.equals(authMode)) {
+            authData.setPhotoData(photoData); //0x42模式
+        }
+
+        // 加密认证数据
+        String s;
+        try {
+            s = objectMapper.writeValueAsString(authData);
+        } catch (JsonProcessingException jpe) {
+            log.error("{}:{}", ResponseConstants.RESPONSE_MESSAGE_JSON_PARSE_FAILED, jpe);
+            return new CommonResponseVO().failed(ResponseConstants.RESPONSE_RESULT_FAILED,
+                    ResponseConstants.RESPONSE_MESSAGE_JSON_PARSE_FAILED);
+        }
+
+        String authDataEnc = uKeyService.sm4Encrypt(encKey, s);
+
+        AuthDataTO.BizData bizData = new AuthDataTO.BizData();
+        bizData.setAuthData(authDataEnc);
+        bizData.setAuthMode(authMode);
+        String timeStamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
+        bizData.setTimeStamp(timeStamp);
+
+        AuthDataTO authDataTo = new AuthDataTO();
+        authDataTo.setBizData(bizData);
+        // 业务数据签名
+        try {
+            authDataTo.setSign(uKeyService.digestECCSign(objectMapper.writeValueAsString(bizData)));
+        } catch (JsonProcessingException jpe) {
+            log.error("{}:{}", ResponseConstants.RESPONSE_MESSAGE_JSON_PARSE_FAILED, jpe);
+            return new CommonResponseVO().failed(ResponseConstants.RESPONSE_RESULT_FAILED,
+                    ResponseConstants.RESPONSE_MESSAGE_JSON_PARSE_FAILED);
+        }
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setBearerAuth(token);
+        headers.setContentType(MediaType.APPLICATION_JSON);
+
+//        log.info("authDataTo: {}", JSONUtil.toJsonPrettyStr(authDataTo));
+        HttpEntity<AuthDataTO> entity = new HttpEntity<>(authDataTo, headers);
+
+        ResponseEntity<ApiResponse<AuthRepData>> exchange = restTemplate.exchange(rzUrl, HttpMethod.POST, entity, new ParameterizedTypeReference<ApiResponse<AuthRepData>>() {
+        });
+
+        ApiResponse<AuthRepData> response = exchange.getBody();
+        log.info("ApiResponse<AuthRepData> response:{}", JSON.toJSONString(response));
+        if (response != null) {
+            if (response.getCode() != 0) {
+                return new CommonResponseVO().failed(ResponseConstants.RESPONSE_RESULT_FAILED,
+                        response.getMsg());
+            }
+
+            AuthRepData data = response.getData();
+
+
+            String sign = data.getSign();
+            AuthRepData.BizData retBizData = data.getBizData();
+
+            AuthSignData authSignData = new AuthSignData();
+            authSignData.setAuthResult(retBizData.isAuthResult());
+            authSignData.setTimeStamp(timeStamp);
+            authSignData.setUsername(username);
+            authSignData.setName(name);
+            authSignData.setIdCard(idCard);
+
+            boolean verify;
+            try {
+                verify = uKeyService.digestECCVerify(serverPubKey, objectMapper.writeValueAsString(authSignData), sign);
+            } catch (JsonProcessingException jpe) {
+                log.error("{}:{}", ResponseConstants.RESPONSE_MESSAGE_JSON_PARSE_FAILED, jpe);
+                return new CommonResponseVO().failed(ResponseConstants.RESPONSE_RESULT_FAILED,
+                        ResponseConstants.RESPONSE_MESSAGE_JSON_PARSE_FAILED);
+            }
+
+            if (!verify) {
+                return new CommonResponseVO().failed(ResponseConstants.RESPONSE_RESULT_FAILED,
+                        ResponseConstants.RESPONSE_MESSAGE_ERROR_SIGN);
+            }
+
+            return new CommonResponseVO().success(String.valueOf(retBizData.isAuthResult()),
+                    ResponseConstants.RESPONSE_MESSAGE_SUCCESS);
+        } else {
+            return new CommonResponseVO().failed(ResponseConstants.RESPONSE_RESULT_FAILED,
+                    ResponseConstants.RESPONSE_MESSAGE_REQUEST_FAILED);
+        }
+
+    }
+}

+ 152 - 0
src/main/java/com/jkcredit/identity/service/Impl/TokenServiceImpl.java

@@ -0,0 +1,152 @@
+package com.jkcredit.identity.service.Impl;
+
+import cn.hutool.json.JSONUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.jkcredit.identity.constant.CommonConstants;
+import com.jkcredit.identity.model.to.HandTO;
+import com.jkcredit.identity.model.to.LoginTO;
+import com.jkcredit.identity.model.vo.ApiResponse;
+import com.jkcredit.identity.model.vo.HandVo;
+import com.jkcredit.identity.model.vo.TokenVo;
+import com.jkcredit.identity.service.TokenService;
+import com.jkcredit.identity.util.TokenConCurrentHashMapUtil;
+import com.zdab.ukey.service.UKeyService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.PostConstruct;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Map;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@Service
+@Slf4j
+public class TokenServiceImpl implements TokenService {
+    @Value("${rz.info.username}")
+    String username;
+    @Value("${rz.info.password}")
+    String password;
+    @Value("${rz.info.url}")
+    String url;
+
+    private static String handUrl;
+    private static String tokenUrl;
+    @Autowired
+    private UKeyService uKeyService;
+    @Autowired
+    private RestTemplate restTemplate;
+    @Autowired
+    StringRedisTemplate stringRedisTemplate;
+    @Autowired
+    ObjectMapper objectMapper;
+
+    @PostConstruct
+    public void init() {
+        handUrl = url + "/ab/auth/hand";
+        tokenUrl = url + "/ab/auth/token";
+    }
+
+    @Override
+    public TokenVo getToken() {
+        Map<String, TokenVo> tokenVoMap = TokenConCurrentHashMapUtil.getInstance();
+        if (tokenVoMap.size() == 0) {
+            return queryToken();
+        } else {
+            return tokenVoMap.get(CommonConstants.TOKEN_KEY);
+        }
+    }
+
+    @Override
+    public TokenVo queryToken() {
+        log.info("**认证握手**");
+        HandTO handTo = new HandTO();
+        String timeStamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
+        handTo.setTimeStamp(timeStamp);
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        // 握手阶段请求头需携带用户名
+        headers.set("X-Main-Id", username);
+        log.info("username:{}", username);
+        log.info("password:{}", password);
+        log.info("handUrl:{}", handUrl);
+        log.info("handTo: {}", JSONUtil.toJsonPrettyStr(handTo));
+        HttpEntity<HandTO> entity = new HttpEntity<>(handTo, headers);
+        ResponseEntity<ApiResponse<HandVo>> exchange = restTemplate.exchange(handUrl, HttpMethod.POST, entity, new ParameterizedTypeReference<ApiResponse<HandVo>>() {
+        });
+
+        ApiResponse<HandVo> response = exchange.getBody();
+
+        String svrRandom = "";
+        if (response != null) {
+            if (response.getCode() != 0) {
+                log.info("err code: {}, err msg: {}", response.getCode(), response.getMsg());
+                return null;
+            }
+            log.info("handVo: {}", JSONUtil.toJsonPrettyStr(response.getData()));
+            svrRandom = response.getData().getSvrRandom();
+
+        }
+        log.info("**获取令牌**");
+        LoginTO.BizData bizData = new LoginTO.BizData();
+        bizData.setUsername(username);
+        bizData.setCredentials(password);
+        timeStamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
+        bizData.setTimeStamp(timeStamp);
+        // 业务数据签名需设置上服务端随机数
+        bizData.setR1(svrRandom);
+        bizData.setR2(uKeyService.genRandomBytes(16));
+
+        LoginTO loginTo = new LoginTO();
+        loginTo.setBizData(bizData);
+        String sign = "";
+        try {
+            sign = uKeyService.digestECCSign(objectMapper.writeValueAsString(bizData));
+            log.info(sign);
+        } catch (Exception e) {
+            log.error("digestECCSign.Exception:", e);
+            return null;
+        }
+
+        loginTo.setSign(sign);
+        // 请求时不要携带随机数
+        bizData.setR1(null);
+
+        log.info("LoginTo: {}", JSONUtil.toJsonPrettyStr(loginTo));
+        headers.clear();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<LoginTO> entity2 = new HttpEntity<>(loginTo, headers);
+
+        ResponseEntity<ApiResponse<TokenVo>> exchange2 = restTemplate.exchange(tokenUrl, HttpMethod.POST, entity2,
+                new ParameterizedTypeReference<ApiResponse<TokenVo>>() {
+                });
+
+        ApiResponse<TokenVo> response2 = exchange2.getBody();
+
+        if (response2 != null) {
+            if (response2.getCode() != 0) {
+                log.info("err code: {}, err msg: {}", response2.getCode(), response2.getMsg());
+                return null;
+            }
+
+            TokenVo tokenVo = response2.getData();
+            log.info("tokenVo: {}", JSONUtil.toJsonPrettyStr(tokenVo));
+            tokenVo.setEncKey(uKeyService.envelopedDecrypt(tokenVo.getEncKey()));
+            tokenVo.setUsername(username);
+            TokenConCurrentHashMapUtil.updateToken(tokenVo);
+            return tokenVo;
+        } else {
+            return null;
+        }
+    }
+}

+ 21 - 0
src/main/java/com/jkcredit/identity/service/TokenService.java

@@ -0,0 +1,21 @@
+package com.jkcredit.identity.service;
+
+import com.jkcredit.identity.model.vo.TokenVo;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+public interface TokenService {
+    /**
+     * 查询token
+     * @return
+     */
+    TokenVo queryToken();
+
+    /**
+     * 获取token
+     * @return
+     */
+    TokenVo getToken();
+}

+ 23 - 0
src/main/java/com/jkcredit/identity/task/TokenTask.java

@@ -0,0 +1,23 @@
+package com.jkcredit.identity.task;
+
+import com.jkcredit.identity.service.TokenService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@Component
+@Slf4j
+public class TokenTask {
+    @Autowired
+    TokenService tokenService;
+
+    @Scheduled(cron = "0 0 0/1 * * ?", zone = "Asia/Shanghai")
+    public void refreshToken() {
+        tokenService.queryToken();
+    }
+}

+ 116 - 0
src/main/java/com/jkcredit/identity/util/DESUtil.java

@@ -0,0 +1,116 @@
+package com.jkcredit.identity.util;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import sun.misc.BASE64Encoder;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESKeySpec;
+import java.io.UnsupportedEncodingException;
+import java.security.SecureRandom;
+
+/**
+ * @description:
+ * @author: sunzhaoning
+ * @create: 2019-05-21 10:48
+ * @version: V1.0
+ **/
+
+public class DESUtil {
+    private static final Log QUERY_LOGGER = LogFactory.getLog("QUERY_LOGGER");
+
+    /**
+     * @param data
+     * @return
+     * @throws Exception
+     * @Method: encrypt
+     * @Description: 加密数据
+     * @date 2016年7月26日
+     */
+    public static String encrypt(String data, String password) {  //对string进行BASE64Encoder转换
+        byte[] bt = encryptByKey(data.getBytes(), password);
+        BASE64Encoder base64en = new BASE64Encoder();
+        bt = base64en.encode(bt).getBytes();
+        try {
+            return new String(bt,"UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * @param data
+     * @return
+     * @throws Exception
+     * @Method: encrypt
+     * @Description: 解密数据
+     * @date 2016年7月26日
+     */
+    public static String decrypt(String data, String password){
+        String result = "";
+        try {
+            sun.misc.BASE64Decoder base64en = new sun.misc.BASE64Decoder();
+            byte[] bt = decrypt(base64en.decodeBuffer(data), password);
+            result = new String(bt,"UTF-8");
+        } catch (Exception e) {
+            QUERY_LOGGER.info("decrypt Exception:" + e);
+        }
+
+        return result;
+    }
+
+    /**
+     * 加密
+     *
+     * @param datasource byte[]
+     * @param key        String
+     * @return byte[]
+     */
+    private static byte[] encryptByKey(byte[] datasource, String key) {
+        try {
+            SecureRandom random = new SecureRandom();
+
+            DESKeySpec desKey = new DESKeySpec(key.getBytes());
+            //创建一个密匙工厂,然后用它把DESKeySpec转换成
+            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
+            SecretKey securekey = keyFactory.generateSecret(desKey);
+            //Cipher对象实际完成加密操作
+            Cipher cipher = Cipher.getInstance("DES");
+            //用密匙初始化Cipher对象
+            cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
+            //现在,获取数据并加密
+            //正式执行加密操作
+            return cipher.doFinal(datasource);
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 解密
+     *
+     * @param src byte[]
+     * @param key String
+     * @return byte[]
+     * @throws Exception
+     */
+    private static byte[] decrypt(byte[] src, String key) throws Exception {
+        // DES算法要求有一个可信任的随机数源
+        SecureRandom random = new SecureRandom();
+        // 创建一个DESKeySpec对象
+        DESKeySpec desKey = new DESKeySpec(key.getBytes());
+        // 创建一个密匙工厂
+        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
+        // 将DESKeySpec对象转换成SecretKey对象
+        SecretKey securekey = keyFactory.generateSecret(desKey);
+        // Cipher对象实际完成解密操作
+        Cipher cipher = Cipher.getInstance("DES");
+        // 用密匙初始化Cipher对象
+        cipher.init(Cipher.DECRYPT_MODE, securekey, random);
+        // 真正开始解密操作
+        return cipher.doFinal(src);
+    }
+}

+ 26 - 0
src/main/java/com/jkcredit/identity/util/TokenConCurrentHashMapUtil.java

@@ -0,0 +1,26 @@
+package com.jkcredit.identity.util;
+
+import com.jkcredit.identity.constant.CommonConstants;
+import com.jkcredit.identity.model.vo.TokenVo;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+public enum TokenConCurrentHashMapUtil {
+    // 实例
+    INSTANCE;
+
+    private static ConcurrentHashMap<String, TokenVo> concurrentHashMap = new ConcurrentHashMap<>();
+
+    public static ConcurrentHashMap<String, TokenVo> getInstance () {
+        return concurrentHashMap;
+    }
+
+    public static void updateToken(TokenVo tokenVo) {
+        concurrentHashMap.put(CommonConstants.TOKEN_KEY, tokenVo);
+    }
+
+}

+ 11 - 0
src/main/resources/application.yml

@@ -0,0 +1,11 @@
+server:
+  port: 18085
+rz:
+  info:
+    username: "pt3"
+    password: "123456"
+    url: "https://120.37.177.102:18443"
+    authMode-0x40: "0x40"
+    authMode-0x42: "0x42"
+aes:
+  secret: a282fe4eb9928nn3

+ 61 - 0
src/main/resources/logback-spring.xml

@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="false" scan="false">
+    <springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue=""/>
+    <property name="log.path" value="logs"/>
+    <!-- 彩色日志格式 -->
+    <property name="CONSOLE_LOG_PATTERN"
+              value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
+    <!-- 彩色日志依赖的渲染类 -->
+    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
+    <conversionRule conversionWord="wex"
+                    converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
+    <conversionRule conversionWord="wEx"
+                    converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
+    <!-- Console log output -->
+    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+        </encoder>
+    </appender>
+
+    <!-- Log file error output -->
+    <appender name="errorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/error/error.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${log.path}/error/%d{yyyy-MM,aux}/error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <maxFileSize>50MB</maxFileSize>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>ERROR</level>
+        </filter>
+    </appender>
+
+
+    <!-- Log file debug output -->
+    <appender name="sourceLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 过滤器,只记录WARN级别的日志 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>INFO</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+        <file>${log.path}/source/source.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${log.path}/source/%d{yyyy-MM,aux}/source-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <maxFileSize>50MB</maxFileSize>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- Level: FATAL 0  ERROR 3  WARN 4  INFO 6  DEBUG 7 -->
+    <root level="INFO">
+        <appender-ref ref="console"/>
+        <appender-ref ref="sourceLog"/>
+        <appender-ref ref="errorLog"/>
+    </root>
+</configuration>

+ 13 - 0
src/test/java/com/jkcredit/identity/IdentityVerifyApplicationTests.java

@@ -0,0 +1,13 @@
+package com.jkcredit.identity;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class IdentityVerifyApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}