From 0e2076edb292e1227a1c4e8380991d0059bedcfb Mon Sep 17 00:00:00 2001 From: free will <2647778488@qq.com> Date: Thu, 20 Aug 2020 21:07:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=AD=A3=E5=9C=A8=E7=9D=80=E6=89=8B=E6=9B=B4?= =?UTF-8?q?=E6=94=B9OA=E7=9A=84=E6=B3=A8=E5=86=8C=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=EF=BC=8C=E5=B0=9A=E6=9C=AA=E8=B0=83=E9=80=9A...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mis_rsa_public.pem | 9 + ndn/BlockSuccessUsers.properties | 5 +- ndn/settings.properties | 8 +- src/main/java/cn/minoa/MainApp.java | 4 +- .../dataRequestInterface/MinoaDataAPI.java | 1 + src/main/java/cn/minoa/util/InstallTool.java | 91 +++ src/main/java/cn/minoa/util/RSACrypto.java | 274 +++++----- .../java/cn/minoa/util/RSACryptoByQJH.java | 516 +++++++++--------- .../java/cn/minoa/util/RSACryptoTest.java | 366 ++++++------- .../view/login/LoginOverviewController.java | 136 ++++- .../login/NDNBlockChainConnectClient.java | 268 +++++++-- .../NDNBlockChainConnectClientByWefree.java | 412 ++++++++++++++ .../cn/minoa/view/login/RSACryptoByWgh.java | 330 +++++++++++ .../login/RegisterOverviewController.java | 184 +++++-- .../java/cn/minoa/view/login/UtilByWgh.java | 17 + .../cn/minoa/view/login/testRegister.java | 7 +- .../fxml/login/RegisterOverview.fxml | 8 +- 17 files changed, 1941 insertions(+), 695 deletions(-) create mode 100644 mis_rsa_public.pem create mode 100644 src/main/java/cn/minoa/util/InstallTool.java create mode 100644 src/main/java/cn/minoa/view/login/NDNBlockChainConnectClientByWefree.java create mode 100644 src/main/java/cn/minoa/view/login/RSACryptoByWgh.java create mode 100644 src/main/java/cn/minoa/view/login/UtilByWgh.java diff --git a/mis_rsa_public.pem b/mis_rsa_public.pem new file mode 100644 index 0000000..818079e --- /dev/null +++ b/mis_rsa_public.pem @@ -0,0 +1,9 @@ +-----BEGIN RSA Public Key----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArQpGd3+hMWsc+Wbrt8Rn +Md175NkLASAHjdq1W2mySrgzTEzo4wWegcxp/Jgau0Chu4Sy4vRXfqjv8hIuUqaT +mdETkmwv4RM6lTM+neDCV+vWolE+KlLAaBEPRW54EdkinIbLGeK69OWDVvAnkKVx +ma6WuZeVpbj6W76Cc90426OFEH8eHHWg8QlG1QX8Z+2AfO/SzRjL1UBvYNzMg3Yr +1+5W/km8Zc/vj5zDBOh85dd9zvxh2lcRQeX0T9akdlygWyFc/MPwuka0Q24ie5EX +C1z6KCJTa92cF8cj1Mnp7MLjosW5EqfN66wMpM5VMB7/0asufFP1u/B1rd0B7MJa +DwIDAQAB +-----END RSA Public Key----- diff --git a/ndn/BlockSuccessUsers.properties b/ndn/BlockSuccessUsers.properties index ba345dd..e96731d 100644 --- a/ndn/BlockSuccessUsers.properties +++ b/ndn/BlockSuccessUsers.properties @@ -1,2 +1,3 @@ -#commit changes: delete a prefix -#Fri Apr 17 20:54:49 CST 2020 +#commit changes: add a prefix +#Thu Aug 20 20:41:42 CST 2020 +34445C9BE3AE53B385A8F4C1625D6150=34445C9BE3AE53B385A8F4C1625D6150 diff --git a/ndn/settings.properties b/ndn/settings.properties index f6b8ec2..d27372f 100644 --- a/ndn/settings.properties +++ b/ndn/settings.properties @@ -1,11 +1,11 @@ #\u4FEE\u6539\u914D\u7F6E\u6587\u4EF6 -#Sat Jun 13 22:34:20 CST 2020 +#Wed Aug 19 21:32:16 CST 2020 KeyName=/MYGOD loginUserName=FDF5A6F1F2B78ADE3DC7700AEFEF5C0F -ndnBlockChainIPAddress=116.77.74.140 -ServerIPAddress=116.77.74.139 +ndnBlockChainIPAddress=121.15.171.91 +ServerIPAddress=121.15.171.91 ThreadNumberForFileTransfer=5 -ndnBlockChainPortAddress=9001 +ndnBlockChainPortAddress=6363 DataPackagePrefix=/ndn/edu/pkusz/OA LoginStatus=false loginPassWord=A1B9652D9ED940B8FC63453C50CB3337 diff --git a/src/main/java/cn/minoa/MainApp.java b/src/main/java/cn/minoa/MainApp.java index b1eff68..e88d1ca 100644 --- a/src/main/java/cn/minoa/MainApp.java +++ b/src/main/java/cn/minoa/MainApp.java @@ -1082,9 +1082,11 @@ public class MainApp extends Application { System.out.println("login status: "+isLoginning); System.out.println("loginer name: "+m_loginer.getUserName()); System.out.println("loginer password: "+m_loginer.getPassWord()); + String loginStringForNDNBlock=loginerController.getLoginJsonStringForBlock( + m_loginer.getUserName(),m_loginer.getPassWord()); String loginString=loginerController.getLoginJsonRSAString( m_loginer.getUserName(),m_loginer.getPassWord()); - if(loginerController.checkPass(loginString)){ + if(loginerController.checkPass(loginStringForNDNBlock,loginString)){ m_flag=true; } } diff --git a/src/main/java/cn/minoa/dataRequestInterface/MinoaDataAPI.java b/src/main/java/cn/minoa/dataRequestInterface/MinoaDataAPI.java index 6e5b54f..b6db2fa 100644 --- a/src/main/java/cn/minoa/dataRequestInterface/MinoaDataAPI.java +++ b/src/main/java/cn/minoa/dataRequestInterface/MinoaDataAPI.java @@ -484,6 +484,7 @@ public class MinoaDataAPI { +"/" +mainApp.loginer.getUserName()+"/"+(System.currentTimeMillis()/1000+MainApp.timeStampBias)); Interest interest = new Interest(name); interest.setMustBeFresh(true); +// if(orderPrefix.equals("/login")){ if(orderPrefix.equals("/register")||orderPrefix.equals("/login")){ Base64.Decoder base64Decoder = Base64.getMimeDecoder() ; interest.setApplicationParameters(new Blob(base64Decoder.decode(requestStr))); diff --git a/src/main/java/cn/minoa/util/InstallTool.java b/src/main/java/cn/minoa/util/InstallTool.java new file mode 100644 index 0000000..b44415b --- /dev/null +++ b/src/main/java/cn/minoa/util/InstallTool.java @@ -0,0 +1,91 @@ +package cn.minoa.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.channels.FileChannel; + +public class InstallTool { + public static boolean hasRegiste = false ; + + private static void copyFileUsingFileChannels(File source, File dest) throws IOException { + FileChannel inputChannel = null; + FileChannel outputChannel = null; + try { + inputChannel = new FileInputStream(source).getChannel(); + outputChannel = new FileOutputStream(dest).getChannel(); + outputChannel.transferFrom(inputChannel, 0, inputChannel.size()); + } finally { + inputChannel.close(); + outputChannel.close(); + } + } + + private static void copyFolder(String resource, String target) throws Exception { + System.out.println("copy file from " + resource + " >>>>>>>>>>>> " + target); + File resourceFile = new File(resource); + if (!resourceFile.exists()) { + throw new Exception("源目标路径:[" + resource + "] 不存在..."); + } + File targetFile = new File(target); + if (!targetFile.exists()) { + targetFile.mkdir(); + } + // 获取源文件夹下的文件夹或文件 + File[] resourceFiles = resourceFile.listFiles(); + for (File file : resourceFiles) { + File targetFile1 = new File(target + File.separator + file.getName()); + // 复制文件 + if (file.isFile()) { + copyFileUsingFileChannels(file,targetFile1) ; + } + // 复制文件夹 + if (file.isDirectory()) {// 复制源文件夹 + String dir1 = file.getAbsolutePath(); + String dir2 = targetFile1.getAbsolutePath(); + copyFolder(dir1, dir2); + } + } + + } + + public static boolean firstInstall(){ + String homeDir = System.getProperty("user.home") ; + String curDir = System.getProperty("user.dir") ; + + File flagFile = new File(curDir + File.separator + "update.md"); + if(!flagFile.exists()) return true ; + + flagFile.delete(); + + File file = new File(homeDir + File.separator + "ndn") ; + if(!file.exists()) { + try { + copyFolder(curDir + File.separator + "ndn", file.getAbsolutePath()); + } catch (Exception e) { + return false ; + } + }else{ + try { + copyFolder(file.getAbsolutePath(),curDir + File.separator + "ndn"); + }catch (Exception e){ + return false ; + } + } + return false; + } + + public static void updateBackup(){ +// if(!hasRegiste) return ; + String homeDir = System.getProperty("user.home") ; + String curDir = System.getProperty("user.dir") ; + try { + copyFolder(curDir + File.separator + "ndn" , homeDir +File.separator+ "ndn"); + } catch (Exception e) { + + } + return ; + } + +} diff --git a/src/main/java/cn/minoa/util/RSACrypto.java b/src/main/java/cn/minoa/util/RSACrypto.java index c742be3..51bc17f 100644 --- a/src/main/java/cn/minoa/util/RSACrypto.java +++ b/src/main/java/cn/minoa/util/RSACrypto.java @@ -1,149 +1,149 @@ -package cn.minoa.util; - -import java.security.*; -import java.security.spec.InvalidKeySpecException; -import java.util.Base64; -import javax.crypto.Cipher; - -//import utilcode.; -//import com.blankj.utilcode.util.EncryptUtils; -// utilcode: https://blog.csdn.net/a940659387/article/details/82116556?utm_source=blogxgwz5 - -// RSA算法实现 -// 原博文:https://blog.csdn.net/super_cui/article/details/70821268 -// 字符串转公钥:https://blog.csdn.net/petib_wangwei/article/details/37601081 - -public class RSACrypto { - private final static String RSA = "RSA"; -// public static PublicKey uk; -// public static PrivateKey rk; - - private static PublicKey getPubKey() { - String pubKey= "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3UIWR510Jlwk6y287DfW" + - "WpsCxafpVr2QLeqAaR04qOaaaqXuhZbUoaxgS2HjVNje9XXiZOArLXGJLKwhfUpr" + - "YwpSIfX6DNWhHUKcwYNca2dkzO10NXPzY7SLgDP9yYyyIV42S/QCCGZ7ku7en/Ve" + - "R/x3CIAOchoBSt6ZRh7iGwl0s5zwVTPF3is4W+46vUECkmbi8HYRjSCEvdAqo7B9" + - "74vNb8tCrwmhztQ3+IdImukSF5/QXMCuaUKLz9CNBZ8pUl45HruG/YxNeJXIC9MV" + - "G1pNZ6D4pBwychwLoM16qjH8/dxZnaIvK8ru09cFNYTowBUOma8u9dpQsMD4+U8O" + - "tQIDAQAB"; - return getPubKey(pubKey); - } - - private static PublicKey getPubKey(String pubKey) { - PublicKey publicKey = null; - try { - java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec( - Base64.getDecoder().decode(pubKey)); - // RSA对称加密算法 - java.security.KeyFactory keyFactory; - keyFactory = java.security.KeyFactory.getInstance(RSA); - // 取公钥匙对象 - publicKey = keyFactory.generatePublic(bobPubKeySpec); - } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { - e.printStackTrace(); - } - return publicKey; - } - - private static byte[] encrypt(String text, PublicKey pubRSA) throws Exception{ - Cipher cipher = Cipher.getInstance(RSA); - cipher.init(Cipher.ENCRYPT_MODE, pubRSA); - return cipher.doFinal(text.getBytes()); - } - - - // 加密字符串 - public static String encrypt(String text) { - //使用默认公钥 - PublicKey publicKey=getPubKey(); - try { - return byte2hex(encrypt(text, publicKey)); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - public static String encrypt(String text,String pubKey) { - //先将公钥生成出来 - PublicKey publicKey=getPubKey(pubKey); - try { - return byte2hex(encrypt(text, publicKey)); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - public static String byte2hex(byte[] b) { - String hs = ""; - String stmp = ""; - for (int n = 0; n < b.length; n++) { - stmp = Integer.toHexString(b[n] & 0xFF); - if (stmp.length() == 1) - hs += ("0" + stmp); - else - hs += stmp; - } - return hs.toUpperCase(); - } - - public static byte[] hex2byte(byte[] b) { - if ((b.length % 2) != 0) - throw new IllegalArgumentException("长度不是偶数"); - - byte[] b2 = new byte[b.length / 2]; - - for (int n = 0; n < b.length; n += 2) { - String item = new String(b, n, 2); - b2[n / 2] = (byte) Integer.parseInt(item, 16); - } - return b2; - } - -// public static void generateKey() throws Exception { -// KeyPairGenerator gen = KeyPairGenerator.getInstance(RSA); -// gen.initialize(512, new SecureRandom()); -// KeyPair keyPair = gen.generateKeyPair(); -// uk = keyPair.getPublic(); -// rk = keyPair.getPrivate(); +//package cn.minoa.util; +// +//import java.security.*; +//import java.security.spec.InvalidKeySpecException; +//import java.util.Base64; +//import javax.crypto.Cipher; +// +////import utilcode.; +////import com.blankj.utilcode.util.EncryptUtils; +//// utilcode: https://blog.csdn.net/a940659387/article/details/82116556?utm_source=blogxgwz5 +// +//// RSA算法实现 +//// 原博文:https://blog.csdn.net/super_cui/article/details/70821268 +//// 字符串转公钥:https://blog.csdn.net/petib_wangwei/article/details/37601081 +// +//public class RSACrypto { +// private final static String RSA = "RSA"; +//// public static PublicKey uk; +//// public static PrivateKey rk; +// +// private static PublicKey getPubKey() { +// String pubKey= "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3UIWR510Jlwk6y287DfW" + +// "WpsCxafpVr2QLeqAaR04qOaaaqXuhZbUoaxgS2HjVNje9XXiZOArLXGJLKwhfUpr" + +// "YwpSIfX6DNWhHUKcwYNca2dkzO10NXPzY7SLgDP9yYyyIV42S/QCCGZ7ku7en/Ve" + +// "R/x3CIAOchoBSt6ZRh7iGwl0s5zwVTPF3is4W+46vUECkmbi8HYRjSCEvdAqo7B9" + +// "74vNb8tCrwmhztQ3+IdImukSF5/QXMCuaUKLz9CNBZ8pUl45HruG/YxNeJXIC9MV" + +// "G1pNZ6D4pBwychwLoM16qjH8/dxZnaIvK8ru09cFNYTowBUOma8u9dpQsMD4+U8O" + +// "tQIDAQAB"; +// return getPubKey(pubKey); // } - -// public final static String encrypt(String text) { +// +// private static PublicKey getPubKey(String pubKey) { +// PublicKey publicKey = null; // try { -// return byte2hex(encrypt(text, uk)); -// } catch (Exception e) { +// java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec( +// Base64.getDecoder().decode(pubKey)); +// // RSA对称加密算法 +// java.security.KeyFactory keyFactory; +// keyFactory = java.security.KeyFactory.getInstance(RSA); +// // 取公钥匙对象 +// publicKey = keyFactory.generatePublic(bobPubKeySpec); +// } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { // e.printStackTrace(); // } -// return null; +// return publicKey; // } - -// public final static String decrypt(String data) { -// try { -// return new String(decrypt(hex2byte(data.getBytes()))); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// return null; -// } - -// private static byte[] decrypt(byte[] src) throws Exception { +// +// private static byte[] encrypt(String text, PublicKey pubRSA) throws Exception{ // Cipher cipher = Cipher.getInstance(RSA); -// cipher.init(Cipher.DECRYPT_MODE, rk); -// return cipher.doFinal(src); +// cipher.init(Cipher.ENCRYPT_MODE, pubRSA); +// return cipher.doFinal(text.getBytes()); // } - -// //just for test -// public static void main(String args[]) { +// +// +// // 加密字符串 +// public static String encrypt(String text) { +// //使用默认公钥 +// PublicKey publicKey=getPubKey(); // try { -// RSACrypto.generateKey(); -// String cipherText = RSACrypto.encrypt("cryptology"); -// System.out.println("密文是:" + cipherText); -// String plainText = RSACrypto.decrypt(cipherText); -// System.out.println("明文是:" + plainText); +// return byte2hex(encrypt(text, publicKey)); // } catch (Exception e) { // e.printStackTrace(); // } +// return null; // } -} - +// +// public static String encrypt(String text,String pubKey) { +// //先将公钥生成出来 +// PublicKey publicKey=getPubKey(pubKey); +// try { +// return byte2hex(encrypt(text, publicKey)); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// return null; +// } +// +// public static String byte2hex(byte[] b) { +// String hs = ""; +// String stmp = ""; +// for (int n = 0; n < b.length; n++) { +// stmp = Integer.toHexString(b[n] & 0xFF); +// if (stmp.length() == 1) +// hs += ("0" + stmp); +// else +// hs += stmp; +// } +// return hs.toUpperCase(); +// } +// +// public static byte[] hex2byte(byte[] b) { +// if ((b.length % 2) != 0) +// throw new IllegalArgumentException("长度不是偶数"); +// +// byte[] b2 = new byte[b.length / 2]; +// +// for (int n = 0; n < b.length; n += 2) { +// String item = new String(b, n, 2); +// b2[n / 2] = (byte) Integer.parseInt(item, 16); +// } +// return b2; +// } +// +//// public static void generateKey() throws Exception { +//// KeyPairGenerator gen = KeyPairGenerator.getInstance(RSA); +//// gen.initialize(512, new SecureRandom()); +//// KeyPair keyPair = gen.generateKeyPair(); +//// uk = keyPair.getPublic(); +//// rk = keyPair.getPrivate(); +//// } +// +//// public final static String encrypt(String text) { +//// try { +//// return byte2hex(encrypt(text, uk)); +//// } catch (Exception e) { +//// e.printStackTrace(); +//// } +//// return null; +//// } +// +//// public final static String decrypt(String data) { +//// try { +//// return new String(decrypt(hex2byte(data.getBytes()))); +//// } catch (Exception e) { +//// e.printStackTrace(); +//// } +//// return null; +//// } +// +//// private static byte[] decrypt(byte[] src) throws Exception { +//// Cipher cipher = Cipher.getInstance(RSA); +//// cipher.init(Cipher.DECRYPT_MODE, rk); +//// return cipher.doFinal(src); +//// } +// +//// //just for test +//// public static void main(String args[]) { +//// try { +//// RSACrypto.generateKey(); +//// String cipherText = RSACrypto.encrypt("cryptology"); +//// System.out.println("密文是:" + cipherText); +//// String plainText = RSACrypto.decrypt(cipherText); +//// System.out.println("明文是:" + plainText); +//// } catch (Exception e) { +//// e.printStackTrace(); +//// } +//// } +//} +// diff --git a/src/main/java/cn/minoa/util/RSACryptoByQJH.java b/src/main/java/cn/minoa/util/RSACryptoByQJH.java index a47e244..b57ad1c 100644 --- a/src/main/java/cn/minoa/util/RSACryptoByQJH.java +++ b/src/main/java/cn/minoa/util/RSACryptoByQJH.java @@ -1,262 +1,262 @@ -package cn.minoa.util; - -import java.io.*; -import java.security.*; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; - -import org.apache.commons.codec.binary.Base64; -//import org.apache.commons.io.IOUtils; -//import org.apache.commons.*; - -import java.io.ByteArrayOutputStream; -import java.security.spec.X509EncodedKeySpec; -//import java.util.*; -import javax.crypto.Cipher; -import java.io.FileReader; - -// RSA算法实现 -// 原博文:https://blog.csdn.net/super_cui/article/details/70821268 -// 字符串转公钥:https://blog.csdn.net/petib_wangwei/article/details/37601081 - -public class RSACryptoByQJH{ - private final static String RSA = "RSA"; - public static PublicKey uk; - // public static PrivateKey rk=get; - - /** */ - /** - * RSA最大加密明文大小 - */ - private static final int MAX_ENCRYPT_BLOCK = 245; - - /** */ - /** - * RSA最大解密密文大小 - */ - private static final int MAX_DECRYPT_BLOCK = 128; - // 忽略首行、末行 - private static String getKey(String filename) throws IOException { - String strKeyPEM = ""; - BufferedReader br = new BufferedReader(new FileReader(filename)); - String line=br.readLine(); - String nextline=""; - while ((line = br.readLine()) != null){ - strKeyPEM+=nextline; - nextline=br.readLine(); - if(nextline!=null){ - strKeyPEM += line ; - } - } - br.close(); - return strKeyPEM; - } - - public static String encrypt2(String data) { - - String filepath = "./ndn/mis_rsa_public.pem"; - File file = new File(filepath); - - - RSAPublicKey publicKey = null; - try { - publicKey = getPublicKey(file.getAbsolutePath()); - } catch (IOException e) { - e.printStackTrace(); - } catch (GeneralSecurityException e) { - e.printStackTrace(); - } - // 对数据加密 - try { - Cipher cipher = Cipher.getInstance(RSA); - cipher.init(Cipher.ENCRYPT_MODE, publicKey); - return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes("UTF-8"), publicKey.getModulus().bitLength())); -// int inputLen = data.getBytes().length; - } catch (Exception e) { - throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e); - } - } - - private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize){ - int maxBlock = 0; - if(opmode == Cipher.DECRYPT_MODE){ - maxBlock = keySize / 8; - }else{ - maxBlock = keySize / 8 - 11; - } - ByteArrayOutputStream out = new ByteArrayOutputStream(); - int offSet = 0; - byte[] buff; - int i = 0; - try{ - while(datas.length > offSet){ - if(datas.length-offSet > maxBlock){ - buff = cipher.doFinal(datas, offSet, maxBlock); - }else{ - buff = cipher.doFinal(datas, offSet, datas.length-offSet); - } - out.write(buff, 0, buff.length); - i++; - offSet = i * maxBlock; - } - }catch(Exception e){ - throw new RuntimeException("加解密阀值为["+maxBlock+"]的数据时发生异常", e); - } - byte[] resultDatas = out.toByteArray(); - try { - out.close(); - } catch (IOException e) { - e.printStackTrace(); - } - // IOUtils.closeQuietly(out); - return resultDatas; - } - - - public static RSAPublicKey getPublicKey(String filename) throws IOException, GeneralSecurityException { - String publicKeyPEM = getKey(filename); - return getPublicKeyFromString(publicKeyPEM); - } - - public static RSAPublicKey getPublicKeyFromString(String key) throws IOException, GeneralSecurityException { - String publicKeyPEM = key; - System.out.println("size: "+publicKeyPEM.getBytes().length); - byte[] encoded = Base64.decodeBase64(publicKeyPEM); - KeyFactory kf = KeyFactory.getInstance("RSA"); - RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(new X509EncodedKeySpec(encoded)); -// RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(new PKCS8EncodedKeySpec(encoded)); - return pubKey; - } - - -// private static PublicKey getPubKey() { -// String pubKey= "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3UIWR510Jlwk6y287DfW" + -// "WpsCxafpVr2QLeqAaR04qOaaaqXuhZbUoaxgS2HjVNje9XXiZOArLXGJLKwhfUpr" + -// "YwpSIfX6DNWhHUKcwYNca2dkzO10NXPzY7SLgDP9yYyyIV42S/QCCGZ7ku7en/Ve" + -// "R/x3CIAOchoBSt6ZRh7iGwl0s5zwVTPF3is4W+46vUECkmbi8HYRjSCEvdAqo7B9" + -// "74vNb8tCrwmhztQ3+IdImukSF5/QXMCuaUKLz9CNBZ8pUl45HruG/YxNeJXIC9MV" + -// "G1pNZ6D4pBwychwLoM16qjH8/dxZnaIvK8ru09cFNYTowBUOma8u9dpQsMD4+U8O" + -// "tQIDAQAB"; -// return getPubKey(pubKey); +//package cn.minoa.util; +// +//import java.io.*; +//import java.security.*; +//import java.security.interfaces.RSAPublicKey; +//import java.security.spec.InvalidKeySpecException; +//import java.security.spec.PKCS8EncodedKeySpec; +// +//import org.apache.commons.codec.binary.Base64; +////import org.apache.commons.io.IOUtils; +////import org.apache.commons.*; +// +//import java.io.ByteArrayOutputStream; +//import java.security.spec.X509EncodedKeySpec; +////import java.util.*; +//import javax.crypto.Cipher; +//import java.io.FileReader; +// +//// RSA算法实现 +//// 原博文:https://blog.csdn.net/super_cui/article/details/70821268 +//// 字符串转公钥:https://blog.csdn.net/petib_wangwei/article/details/37601081 +// +//public class RSACryptoByQJH{ +// private final static String RSA = "RSA"; +// public static PublicKey uk; +// // public static PrivateKey rk=get; +// +// /** */ +// /** +// * RSA最大加密明文大小 +// */ +// private static final int MAX_ENCRYPT_BLOCK = 245; +// +// /** */ +// /** +// * RSA最大解密密文大小 +// */ +// private static final int MAX_DECRYPT_BLOCK = 128; +// // 忽略首行、末行 +// private static String getKey(String filename) throws IOException { +// String strKeyPEM = ""; +// BufferedReader br = new BufferedReader(new FileReader(filename)); +// String line=br.readLine(); +// String nextline=""; +// while ((line = br.readLine()) != null){ +// strKeyPEM+=nextline; +// nextline=br.readLine(); +// if(nextline!=null){ +// strKeyPEM += line ; +// } +// } +// br.close(); +// return strKeyPEM; // } // -// private static PublicKey getPubKey(String pubKey) { -// PublicKey publicKey = null; -// try { -// java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec( -// Base64.getDecoder().decode(pubKey)); -// // RSA对称加密算法 -// java.security.KeyFactory keyFactory; -// keyFactory = java.security.KeyFactory.getInstance(RSA); -// // 取公钥匙对象 -// publicKey = keyFactory.generatePublic(bobPubKeySpec); -// } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { -// e.printStackTrace(); -// } -// return publicKey; -// } - - - -// public static String encrypt(String text,String pubKey) { -// //先将公钥生成出来 -// PublicKey publicKey=getPubKey(pubKey); -// try { -// return byte2hex(encrypt(text, publicKey)); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// return null; -// } - - public static String byte2hex(byte[] b) { - String hs = ""; - String stmp = ""; - for (int n = 0; n < b.length; n++) { - stmp = Integer.toHexString(b[n] & 0xFF); - if (stmp.length() == 1) - hs += ("0" + stmp); - else - hs += stmp; - } - return hs.toUpperCase(); - } - - public static byte[] hex2byte(byte[] b) { - if ((b.length % 2) != 0) - throw new IllegalArgumentException("长度不是偶数"); - - byte[] b2 = new byte[b.length / 2]; - - for (int n = 0; n < b.length; n += 2) { - String item = new String(b, n, 2); - b2[n / 2] = (byte) Integer.parseInt(item, 16); - } - return b2; - } - -// public static void generateKey() throws Exception { -// KeyPairGenerator gen = KeyPairGenerator.getInstance(RSA); -// gen.initialize(512, new SecureRandom()); -// KeyPair keyPair = gen.generateKeyPair(); -// uk = keyPair.getPublic(); -// rk = keyPair.getPrivate(); -// } - -// public final static String encrypt2(String text) { -// try { -// return byte2hex(encrypt(text, uk)); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// return null; -// } - -// public final static String decrypt(String data) { -// try { -//// System.out.println("the data is "+data); -//// System.out.println("the data byte is"+data.getBytes()); -//// // System.out.println("the data byte is-"+decrypt(data)); -//// System.out.println("the data byte is-"+Base64.getDecoder().decode(data.getBytes())); -//// return new String(Base64.getDecoder().decode(decrypt(data.getBytes()))); -// Cipher cipher = Cipher.getInstance("RSA"); -// cipher.init(Cipher.DECRYPT_MODE, rk); -// return new String(cipher.doFinal(org.apache.commons.codec.binary.Base64.decodeBase64(data)), "UTF-8"); +// public static String encrypt2(String data) { // -// // return new String(Base64.getDecoder().decode(decrypt(hex2byte(data.getBytes())))); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// return null; -// } - -// private static byte[] decrypt(byte[] src) throws Exception { -// Cipher cipher = Cipher.getInstance(RSA); -// cipher.init(Cipher.DECRYPT_MODE, rk); -// return cipher.doFinal(src); -// } - - - - - - //just for test -// public static void main(String args[]) { -// try { -// // RSACrypto.generateKey(); -//// String filepath="D:\\wefree\\MIN-VPN\\src\\main\\java\\cn\\minoa\\view\\login\\mis_rsa_pubic.pem";//注意filepath的内容; -//// String filepath="./ndn/mis_rsa_public.pem"; -//// File file=new File(filepath); -//// uk=getPublicKey(file.getAbsolutePath()); -//// uk=getPublicKey("D:\\wefree\\MIN-VPN\\src\\main\\java\\cn\\minoa\\view\\login\\mis_rsa_pubic.pem"); -// String cipherText = RSACrypto.encrypt2("cryptology"); -// System.out.println("密文是:" + cipherText); -// // String plainText = RSACrypto.decrypt(cipherText); -// // System.out.println("明文是:" + plainText); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// } -} +// String filepath = "./ndn/mis_rsa_public.pem"; +// File file = new File(filepath); // +// +// RSAPublicKey publicKey = null; +// try { +// publicKey = getPublicKey(file.getAbsolutePath()); +// } catch (IOException e) { +// e.printStackTrace(); +// } catch (GeneralSecurityException e) { +// e.printStackTrace(); +// } +// // 对数据加密 +// try { +// Cipher cipher = Cipher.getInstance(RSA); +// cipher.init(Cipher.ENCRYPT_MODE, publicKey); +// return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes("UTF-8"), publicKey.getModulus().bitLength())); +//// int inputLen = data.getBytes().length; +// } catch (Exception e) { +// throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e); +// } +// } +// +// private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize){ +// int maxBlock = 0; +// if(opmode == Cipher.DECRYPT_MODE){ +// maxBlock = keySize / 8; +// }else{ +// maxBlock = keySize / 8 - 11; +// } +// ByteArrayOutputStream out = new ByteArrayOutputStream(); +// int offSet = 0; +// byte[] buff; +// int i = 0; +// try{ +// while(datas.length > offSet){ +// if(datas.length-offSet > maxBlock){ +// buff = cipher.doFinal(datas, offSet, maxBlock); +// }else{ +// buff = cipher.doFinal(datas, offSet, datas.length-offSet); +// } +// out.write(buff, 0, buff.length); +// i++; +// offSet = i * maxBlock; +// } +// }catch(Exception e){ +// throw new RuntimeException("加解密阀值为["+maxBlock+"]的数据时发生异常", e); +// } +// byte[] resultDatas = out.toByteArray(); +// try { +// out.close(); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// // IOUtils.closeQuietly(out); +// return resultDatas; +// } +// +// +// public static RSAPublicKey getPublicKey(String filename) throws IOException, GeneralSecurityException { +// String publicKeyPEM = getKey(filename); +// return getPublicKeyFromString(publicKeyPEM); +// } +// +// public static RSAPublicKey getPublicKeyFromString(String key) throws IOException, GeneralSecurityException { +// String publicKeyPEM = key; +// System.out.println("size: "+publicKeyPEM.getBytes().length); +// byte[] encoded = Base64.decodeBase64(publicKeyPEM); +// KeyFactory kf = KeyFactory.getInstance("RSA"); +// RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(new X509EncodedKeySpec(encoded)); +//// RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(new PKCS8EncodedKeySpec(encoded)); +// return pubKey; +// } +// +// +//// private static PublicKey getPubKey() { +//// String pubKey= "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3UIWR510Jlwk6y287DfW" + +//// "WpsCxafpVr2QLeqAaR04qOaaaqXuhZbUoaxgS2HjVNje9XXiZOArLXGJLKwhfUpr" + +//// "YwpSIfX6DNWhHUKcwYNca2dkzO10NXPzY7SLgDP9yYyyIV42S/QCCGZ7ku7en/Ve" + +//// "R/x3CIAOchoBSt6ZRh7iGwl0s5zwVTPF3is4W+46vUECkmbi8HYRjSCEvdAqo7B9" + +//// "74vNb8tCrwmhztQ3+IdImukSF5/QXMCuaUKLz9CNBZ8pUl45HruG/YxNeJXIC9MV" + +//// "G1pNZ6D4pBwychwLoM16qjH8/dxZnaIvK8ru09cFNYTowBUOma8u9dpQsMD4+U8O" + +//// "tQIDAQAB"; +//// return getPubKey(pubKey); +//// } +//// +//// private static PublicKey getPubKey(String pubKey) { +//// PublicKey publicKey = null; +//// try { +//// java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec( +//// Base64.getDecoder().decode(pubKey)); +//// // RSA对称加密算法 +//// java.security.KeyFactory keyFactory; +//// keyFactory = java.security.KeyFactory.getInstance(RSA); +//// // 取公钥匙对象 +//// publicKey = keyFactory.generatePublic(bobPubKeySpec); +//// } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { +//// e.printStackTrace(); +//// } +//// return publicKey; +//// } +// +// +// +//// public static String encrypt(String text,String pubKey) { +//// //先将公钥生成出来 +//// PublicKey publicKey=getPubKey(pubKey); +//// try { +//// return byte2hex(encrypt(text, publicKey)); +//// } catch (Exception e) { +//// e.printStackTrace(); +//// } +//// return null; +//// } +// +// public static String byte2hex(byte[] b) { +// String hs = ""; +// String stmp = ""; +// for (int n = 0; n < b.length; n++) { +// stmp = Integer.toHexString(b[n] & 0xFF); +// if (stmp.length() == 1) +// hs += ("0" + stmp); +// else +// hs += stmp; +// } +// return hs.toUpperCase(); +// } +// +// public static byte[] hex2byte(byte[] b) { +// if ((b.length % 2) != 0) +// throw new IllegalArgumentException("长度不是偶数"); +// +// byte[] b2 = new byte[b.length / 2]; +// +// for (int n = 0; n < b.length; n += 2) { +// String item = new String(b, n, 2); +// b2[n / 2] = (byte) Integer.parseInt(item, 16); +// } +// return b2; +// } +// +//// public static void generateKey() throws Exception { +//// KeyPairGenerator gen = KeyPairGenerator.getInstance(RSA); +//// gen.initialize(512, new SecureRandom()); +//// KeyPair keyPair = gen.generateKeyPair(); +//// uk = keyPair.getPublic(); +//// rk = keyPair.getPrivate(); +//// } +// +//// public final static String encrypt2(String text) { +//// try { +//// return byte2hex(encrypt(text, uk)); +//// } catch (Exception e) { +//// e.printStackTrace(); +//// } +//// return null; +//// } +// +//// public final static String decrypt(String data) { +//// try { +////// System.out.println("the data is "+data); +////// System.out.println("the data byte is"+data.getBytes()); +////// // System.out.println("the data byte is-"+decrypt(data)); +////// System.out.println("the data byte is-"+Base64.getDecoder().decode(data.getBytes())); +////// return new String(Base64.getDecoder().decode(decrypt(data.getBytes()))); +//// Cipher cipher = Cipher.getInstance("RSA"); +//// cipher.init(Cipher.DECRYPT_MODE, rk); +//// return new String(cipher.doFinal(org.apache.commons.codec.binary.Base64.decodeBase64(data)), "UTF-8"); +//// +//// // return new String(Base64.getDecoder().decode(decrypt(hex2byte(data.getBytes())))); +//// } catch (Exception e) { +//// e.printStackTrace(); +//// } +//// return null; +//// } +// +//// private static byte[] decrypt(byte[] src) throws Exception { +//// Cipher cipher = Cipher.getInstance(RSA); +//// cipher.init(Cipher.DECRYPT_MODE, rk); +//// return cipher.doFinal(src); +//// } +// +// +// +// +// +// //just for test +//// public static void main(String args[]) { +//// try { +//// // RSACrypto.generateKey(); +////// String filepath="D:\\wefree\\MIN-VPN\\src\\main\\java\\cn\\minoa\\view\\login\\mis_rsa_pubic.pem";//注意filepath的内容; +////// String filepath="./ndn/mis_rsa_public.pem"; +////// File file=new File(filepath); +////// uk=getPublicKey(file.getAbsolutePath()); +////// uk=getPublicKey("D:\\wefree\\MIN-VPN\\src\\main\\java\\cn\\minoa\\view\\login\\mis_rsa_pubic.pem"); +//// String cipherText = RSACrypto.encrypt2("cryptology"); +//// System.out.println("密文是:" + cipherText); +//// // String plainText = RSACrypto.decrypt(cipherText); +//// // System.out.println("明文是:" + plainText); +//// } catch (Exception e) { +//// e.printStackTrace(); +//// } +//// } +//} +//// diff --git a/src/main/java/cn/minoa/util/RSACryptoTest.java b/src/main/java/cn/minoa/util/RSACryptoTest.java index e6f6895..d06b366 100644 --- a/src/main/java/cn/minoa/util/RSACryptoTest.java +++ b/src/main/java/cn/minoa/util/RSACryptoTest.java @@ -1,184 +1,184 @@ -package cn.minoa.util; - -//import sun.misc.BASE64Decoder; -//import sun.misc.BASE64Encoder; -import org.apache.commons.codec.binary.Base64; - -import javax.crypto.Cipher; -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.security.*; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; - -/** - * create: https://www.jianshu.com/p/87d2148a4298 - * https://www.cnblogs.com/moonsoft/p/12300001.html - **/ -public class RSACryptoTest { - - /** - * 算法名称 - */ - private static final String ALGORITHM = "RSA"; - - /** - * 密钥长度 - */ - private static final int KEY_SIZE = 2048; - - /** - * 随机生成密钥对(包含公钥和私钥) - */ - public static KeyPair generateKeyPair() throws Exception { - // 获取指定算法的密钥对生成器 - KeyPairGenerator gen = KeyPairGenerator.getInstance(ALGORITHM); - // 初始化密钥对生成器(指定密钥长度, 使用默认的安全随机数源) - gen.initialize(KEY_SIZE); - // 随机生成一对密钥(包含公钥和私钥) - return gen.generateKeyPair(); - } - - /** - * 将 公钥/私钥 编码后以 Base64 的格式保存到指定文件 - */ - public static void saveKeyForEncodedBase64(Key key, File keyFile) throws IOException { - // 获取密钥编码后的格式 - byte[] encBytes = key.getEncoded(); - // 转换为 Base64 文本 -// String encBase64 = new BASE64Encoder().encode(encBytes); - String encBase64=Base64.encodeBase64String(encBytes); - // 保存到文件 - IOUtils.writeFile(encBase64, keyFile); - } - - /** - * 根据公钥的 Base64 文本创建公钥对象 - */ - public static PublicKey getPublicKey(String pubKeyBase64) throws Exception { - // 把 公钥的Base64文本 转换为已编码的 公钥bytes -// byte[] encPubKey = new BASE64Decoder().decodeBuffer(pubKeyBase64); - byte[] encPubKey=Base64.decodeBase64(pubKeyBase64); - // 创建 已编码的公钥规格 - X509EncodedKeySpec encPubKeySpec = new X509EncodedKeySpec(encPubKey); - // 获取指定算法的密钥工厂, 根据 已编码的公钥规格, 生成公钥对象 - return KeyFactory.getInstance(ALGORITHM).generatePublic(encPubKeySpec); - } - - /** - * 根据私钥的 Base64 文本创建私钥对象 - */ - public static PrivateKey getPrivateKey(String priKeyBase64) throws Exception { - // 把 私钥的Base64文本 转换为已编码的 私钥bytes -// byte[] encPriKey = new BASE64Decoder().decodeBuffer(priKeyBase64); - byte[] encPriKey =Base64.decodeBase64(priKeyBase64); - // 创建 已编码的私钥规格 - PKCS8EncodedKeySpec encPriKeySpec = new PKCS8EncodedKeySpec(encPriKey); - // 获取指定算法的密钥工厂, 根据 已编码的私钥规格, 生成私钥对象 - return KeyFactory.getInstance(ALGORITHM).generatePrivate(encPriKeySpec); - } - - /** - * 公钥加密数据 - */ - public static byte[] encrypt(byte[] plainData, PublicKey pubKey) throws Exception { - // 获取指定算法的密码器 - Cipher cipher = Cipher.getInstance(ALGORITHM); - // 初始化密码器(公钥加密模型) - cipher.init(Cipher.ENCRYPT_MODE, pubKey); - // 加密数据, 返回加密后的密文 - return cipher.doFinal(plainData); - } - - /** - * 私钥解密数据 - */ - public static byte[] decrypt(byte[] cipherData, PrivateKey priKey) throws Exception { - // 获取指定算法的密码器 - Cipher cipher = Cipher.getInstance(ALGORITHM); - // 初始化密码器(私钥解密模型) - cipher.init(Cipher.DECRYPT_MODE, priKey); - // 解密数据, 返回解密后的明文 - return cipher.doFinal(cipherData); - } - - /** - * 使用配置文件中的公钥进行加密, 返回加密后的数据 - */ - private static byte[] encryptRSAByFile(byte[] plainData, File pubFile) throws Exception { - // 读取公钥文件, 创建公钥对象 - PublicKey pubKey = getPublicKey(IOUtils.readFile(pubFile)); - // 用公钥加密数据 - byte[] cipher = encrypt(plainData, pubKey); - return cipher; - } - - public static byte[] encryptRSA(byte[] plainData) throws Exception { - File pubkeyFile=new File("./ndn/pub.txt"); - return encryptRSAByFile(plainData,pubkeyFile); - } - -// public static byte[] encryptRSA(String plainData) throws Exception { -// return encryptRSA(plainData.getBytes(StandardCharsets.UTF_8)); -// } - - public static String encryptRSAString(String plainData) throws Exception { - byte[] r=encryptRSA(plainData.getBytes(StandardCharsets.UTF_8)); -// return new String(r,StandardCharsets.UTF_8); - String bs=Base64.encodeBase64String(r); - return bs; - } - - // 测试****************************************************************** - public static void main(String[] args) throws Exception { -// // 随机生成一对密钥(包含公钥和私钥) -// KeyPair keyPair = generateKeyPair(); -// // 获取 公钥 和 私钥 -// PublicKey pubKey = keyPair.getPublic(); -// PrivateKey priKey = keyPair.getPrivate(); +//package cn.minoa.util; // -// // 保存 公钥 和 私钥 -// saveKeyForEncodedBase64(pubKey, new File("./ndn/pub.txt")); -// saveKeyForEncodedBase64(priKey, new File("./ndn/pri.txt")); - - - // 原文数据 -// String data = "Hello, World!"; - String data="{\"password\":\"c4ca4238a0b923820dcc509a6f75849b\",\"aesKey\":[35,-82,-128,-99,-38,-54,-7,106,-16,-3,120,-19,4,-74,-94,101],\"command\":\"/login\",\"username\":\"MYGOD\"}"; - - // 客户端: 加密 - byte[] cipherData = clientEncrypt(data.getBytes(StandardCharsets.UTF_8), new File("./ndn/pub.txt")); -// String bs=Base64.encodeBase64String(cipherData); - String bs=new String(cipherData); - - // 服务端: 解密 - byte[] plainData = serverDecrypt(bs.getBytes(), new File("./ndn/pri.txt")); - - - System.out.println(new String(plainData)); - } - - /** - * 客户端加密, 返回加密后的数据 - */ - private static byte[] clientEncrypt(byte[] plainData, File pubFile) throws Exception { - // 读取公钥文件, 创建公钥对象 - PublicKey pubKey = getPublicKey(IOUtils.readFile(pubFile)); - // 用公钥加密数据 - byte[] cipher = encrypt(plainData, pubKey); - return cipher; - } - - /** - * 服务端解密, 返回解密后的数据 - */ - private static byte[] serverDecrypt(byte[] cipherData, File priFile) throws Exception { - // 读取私钥文件, 创建私钥对象 - PrivateKey priKey = getPrivateKey(IOUtils.readFile(priFile)); - // 用私钥解密数据 - byte[] plainData = decrypt(cipherData, priKey); - return plainData; - } - -} +////import sun.misc.BASE64Decoder; +////import sun.misc.BASE64Encoder; +//import org.apache.commons.codec.binary.Base64; +// +//import javax.crypto.Cipher; +//import java.io.File; +//import java.io.IOException; +//import java.nio.charset.StandardCharsets; +//import java.security.*; +//import java.security.spec.PKCS8EncodedKeySpec; +//import java.security.spec.X509EncodedKeySpec; +// +///** +// * create: https://www.jianshu.com/p/87d2148a4298 +// * https://www.cnblogs.com/moonsoft/p/12300001.html +// **/ +//public class RSACryptoTest { +// +// /** +// * 算法名称 +// */ +// private static final String ALGORITHM = "RSA"; +// +// /** +// * 密钥长度 +// */ +// private static final int KEY_SIZE = 2048; +// +// /** +// * 随机生成密钥对(包含公钥和私钥) +// */ +// public static KeyPair generateKeyPair() throws Exception { +// // 获取指定算法的密钥对生成器 +// KeyPairGenerator gen = KeyPairGenerator.getInstance(ALGORITHM); +// // 初始化密钥对生成器(指定密钥长度, 使用默认的安全随机数源) +// gen.initialize(KEY_SIZE); +// // 随机生成一对密钥(包含公钥和私钥) +// return gen.generateKeyPair(); +// } +// +// /** +// * 将 公钥/私钥 编码后以 Base64 的格式保存到指定文件 +// */ +// public static void saveKeyForEncodedBase64(Key key, File keyFile) throws IOException { +// // 获取密钥编码后的格式 +// byte[] encBytes = key.getEncoded(); +// // 转换为 Base64 文本 +//// String encBase64 = new BASE64Encoder().encode(encBytes); +// String encBase64=Base64.encodeBase64String(encBytes); +// // 保存到文件 +// IOUtils.writeFile(encBase64, keyFile); +// } +// +// /** +// * 根据公钥的 Base64 文本创建公钥对象 +// */ +// public static PublicKey getPublicKey(String pubKeyBase64) throws Exception { +// // 把 公钥的Base64文本 转换为已编码的 公钥bytes +//// byte[] encPubKey = new BASE64Decoder().decodeBuffer(pubKeyBase64); +// byte[] encPubKey=Base64.decodeBase64(pubKeyBase64); +// // 创建 已编码的公钥规格 +// X509EncodedKeySpec encPubKeySpec = new X509EncodedKeySpec(encPubKey); +// // 获取指定算法的密钥工厂, 根据 已编码的公钥规格, 生成公钥对象 +// return KeyFactory.getInstance(ALGORITHM).generatePublic(encPubKeySpec); +// } +// +// /** +// * 根据私钥的 Base64 文本创建私钥对象 +// */ +// public static PrivateKey getPrivateKey(String priKeyBase64) throws Exception { +// // 把 私钥的Base64文本 转换为已编码的 私钥bytes +//// byte[] encPriKey = new BASE64Decoder().decodeBuffer(priKeyBase64); +// byte[] encPriKey =Base64.decodeBase64(priKeyBase64); +// // 创建 已编码的私钥规格 +// PKCS8EncodedKeySpec encPriKeySpec = new PKCS8EncodedKeySpec(encPriKey); +// // 获取指定算法的密钥工厂, 根据 已编码的私钥规格, 生成私钥对象 +// return KeyFactory.getInstance(ALGORITHM).generatePrivate(encPriKeySpec); +// } +// +// /** +// * 公钥加密数据 +// */ +// public static byte[] encrypt(byte[] plainData, PublicKey pubKey) throws Exception { +// // 获取指定算法的密码器 +// Cipher cipher = Cipher.getInstance(ALGORITHM); +// // 初始化密码器(公钥加密模型) +// cipher.init(Cipher.ENCRYPT_MODE, pubKey); +// // 加密数据, 返回加密后的密文 +// return cipher.doFinal(plainData); +// } +// +// /** +// * 私钥解密数据 +// */ +// public static byte[] decrypt(byte[] cipherData, PrivateKey priKey) throws Exception { +// // 获取指定算法的密码器 +// Cipher cipher = Cipher.getInstance(ALGORITHM); +// // 初始化密码器(私钥解密模型) +// cipher.init(Cipher.DECRYPT_MODE, priKey); +// // 解密数据, 返回解密后的明文 +// return cipher.doFinal(cipherData); +// } +// +// /** +// * 使用配置文件中的公钥进行加密, 返回加密后的数据 +// */ +// private static byte[] encryptRSAByFile(byte[] plainData, File pubFile) throws Exception { +// // 读取公钥文件, 创建公钥对象 +// PublicKey pubKey = getPublicKey(IOUtils.readFile(pubFile)); +// // 用公钥加密数据 +// byte[] cipher = encrypt(plainData, pubKey); +// return cipher; +// } +// +// public static byte[] encryptRSA(byte[] plainData) throws Exception { +// File pubkeyFile=new File("./ndn/pub.txt"); +// return encryptRSAByFile(plainData,pubkeyFile); +// } +// +//// public static byte[] encryptRSA(String plainData) throws Exception { +//// return encryptRSA(plainData.getBytes(StandardCharsets.UTF_8)); +//// } +// +// public static String encryptRSAString(String plainData) throws Exception { +// byte[] r=encryptRSA(plainData.getBytes(StandardCharsets.UTF_8)); +//// return new String(r,StandardCharsets.UTF_8); +// String bs=Base64.encodeBase64String(r); +// return bs; +// } +// +// // 测试****************************************************************** +// public static void main(String[] args) throws Exception { +//// // 随机生成一对密钥(包含公钥和私钥) +//// KeyPair keyPair = generateKeyPair(); +//// // 获取 公钥 和 私钥 +//// PublicKey pubKey = keyPair.getPublic(); +//// PrivateKey priKey = keyPair.getPrivate(); +//// +//// // 保存 公钥 和 私钥 +//// saveKeyForEncodedBase64(pubKey, new File("./ndn/pub.txt")); +//// saveKeyForEncodedBase64(priKey, new File("./ndn/pri.txt")); +// +// +// // 原文数据 +//// String data = "Hello, World!"; +// String data="{\"password\":\"c4ca4238a0b923820dcc509a6f75849b\",\"aesKey\":[35,-82,-128,-99,-38,-54,-7,106,-16,-3,120,-19,4,-74,-94,101],\"command\":\"/login\",\"username\":\"MYGOD\"}"; +// +// // 客户端: 加密 +// byte[] cipherData = clientEncrypt(data.getBytes(StandardCharsets.UTF_8), new File("./ndn/pub.txt")); +//// String bs=Base64.encodeBase64String(cipherData); +// String bs=new String(cipherData); +// +// // 服务端: 解密 +// byte[] plainData = serverDecrypt(bs.getBytes(), new File("./ndn/pri.txt")); +// +// +// System.out.println(new String(plainData)); +// } +// +// /** +// * 客户端加密, 返回加密后的数据 +// */ +// private static byte[] clientEncrypt(byte[] plainData, File pubFile) throws Exception { +// // 读取公钥文件, 创建公钥对象 +// PublicKey pubKey = getPublicKey(IOUtils.readFile(pubFile)); +// // 用公钥加密数据 +// byte[] cipher = encrypt(plainData, pubKey); +// return cipher; +// } +// +// /** +// * 服务端解密, 返回解密后的数据 +// */ +// private static byte[] serverDecrypt(byte[] cipherData, File priFile) throws Exception { +// // 读取私钥文件, 创建私钥对象 +// PrivateKey priKey = getPrivateKey(IOUtils.readFile(priFile)); +// // 用私钥解密数据 +// byte[] plainData = decrypt(cipherData, priKey); +// return plainData; +// } +// +//} diff --git a/src/main/java/cn/minoa/view/login/LoginOverviewController.java b/src/main/java/cn/minoa/view/login/LoginOverviewController.java index 9320d22..38da76a 100644 --- a/src/main/java/cn/minoa/view/login/LoginOverviewController.java +++ b/src/main/java/cn/minoa/view/login/LoginOverviewController.java @@ -79,8 +79,8 @@ public class LoginOverviewController { @FXML private void handleRegister() { // 初始化时间戳差值 - MainApp.iniTimeStampBias(); - System.out.println("timeStampBias: "+MainApp.timeStampBias); +// MainApp.iniTimeStampBias(); +// System.out.println("timeStampBias: "+MainApp.timeStampBias); // 弹出注册界面 mainApp.showRegisterOverview(); } @@ -102,6 +102,7 @@ public class LoginOverviewController { // 实例化 // mainApp.minoaDataAPI = new MinoaDataAPI(mainApp); String userNameString = userNameFiled.getText().trim(); + userNameString = UtilByWgh.Base64PlusEncode(userNameString); String passWordString = passwordFiled.getText().trim(); if (userNameString.equals("")) { return; @@ -130,7 +131,7 @@ public class LoginOverviewController { error.printStackTrace(); } // 登录验证 -// String loginString = getLoginJsonString(); + String loginStringForNDNBlock = getLoginJsonStringForBlock(userNameString); String loginString= null; try { loginString = getLoginJsonRSAString(); @@ -138,7 +139,8 @@ public class LoginOverviewController { System.out.print("rsa加密失败:"+e.getMessage()); return ; } - boolean isRight = checkPass(loginString); + // 判断后台是否登录成功 + boolean isRight = checkPass(loginStringForNDNBlock,loginString); if (isRight) { // 持久化保存当前用户名和密码 keepLoginInfo(true, userNameString, passWordString); @@ -196,12 +198,53 @@ public class LoginOverviewController { // return flag; // } - public boolean checkPass(String loginJsonString) throws Exception { - // 初始化时间戳差值 - MainApp.iniTimeStampBias(); - System.out.println("timeStampBias: "+MainApp.timeStampBias); + // 用于区块链登录 + public boolean checkPassNDNBlock(String loginStringForNDNBlock){ + // 区块链登录 + System.out.println("checking your password in ndn blockchain firstly..."); + NDNBlockChainConnectClient ndnBlockChainConnectClient = new NDNBlockChainConnectClient(); + // String resString = ndnBlockChainConnectClient.LoginNewUser(loginString); + System.out.println("the login information "+loginStringForNDNBlock); + System.out.println("the login encrypt information "+RSACryptoByWgh.encrypt2(loginStringForNDNBlock)); + String resString = ndnBlockChainConnectClient.loginNewUser(RSACryptoByWgh.encrypt2(loginStringForNDNBlock)); + System.out.println("the login restring "+resString); + JSONObject jsonObject = null; + Integer resCode = null; + String loginmessage = null; + try { + jsonObject = new JSONObject(resString); + System.out.println("the return LOGIN IN CHECK PASS infomation"+ jsonObject); - System.out.println("checking your password..."); + // int resCode = jsonObject.getInt("StatusCode"); + resCode = jsonObject.getInt("StatusCode"); + System.out.println("the return rescode"+ resCode); + loginmessage = jsonObject.getString("Message"); + System.out.println("the return message"+ loginmessage); + + }catch (Exception e){ + e.printStackTrace(); + } + System.out.println("the return rescode second"+ resCode); + if (resCode == 200) { + System.out.println("ndn blockchain login 200"); + return true; + }else{ + System.out.println("ndn blockchain login error "+resCode); + return false; + } + } + + + public boolean checkPass(String loginStringForNDNBlock,String loginJsonString) throws Exception { + // 初始化时间戳差值 +// MainApp.iniTimeStampBias(); +// System.out.println("timeStampBias: "+MainApp.timeStampBias); + if(!checkPassNDNBlock(loginStringForNDNBlock)){ + return false; + } + + // 后台登录 + System.out.println("checking your password finally..."); boolean flag = false; // 发送数据请求 Long seqLong = mainApp.getNewDataReqId(); @@ -593,6 +636,7 @@ public class LoginOverviewController { JSONObject jsonObject = new JSONObject(); String commandString = "/login"; String userNameString = userNameFiled.getText().trim(); + userNameString = UtilByWgh.Base64PlusEncode(userNameString) ; String passWordString = passwordFiled.getText().trim(); if (userNameString == null || passWordString == null) { // 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/ @@ -647,12 +691,86 @@ public class LoginOverviewController { return rsaString; } + // 从前端界面获得登录数据并转换成json格式,用于区块链的登录 + public String getLoginJsonStringForBlock(String username) { + JSONObject jsonObject = new JSONObject(); + String commandString = "Login"; + String type ="user-act"; + String time ="1238237238723287378"; + String userNameString = username; + String passWordString = passwordFiled.getText().trim(); + String prefix ="/"+userNameString; + if (userNameString == null || passWordString == null) { +// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/ + Alert alert = new Alert(AlertType.WARNING); + alert.setTitle("UserName or Password is null"); + alert.setHeaderText("Please correct UserName or Password."); + alert.setContentText("Please correct UserName or Password."); + alert.showAndWait(); + }else{ + // 保存登录信息到本地 +// keepLoginInfo(true,userNameString,passWordString); + } + // 对密码进行哈希加密 + passWordString= EncryptionUtil.getMD5String(passWordString); + mainApp.loginer.setUserName(userNameString); + mainApp.loginer.setPassWord(passWordString); + try { + jsonObject.put("Type", type); + jsonObject.put("Command", commandString); + jsonObject.put("Prefix", prefix); + jsonObject.put("Password", passWordString); + jsonObject.put("Timestamp", time); + } catch (Exception e) { + System.out.println("exception: " + e.getMessage()); + } + return jsonObject.toString(); + } + + // 根据本地保存的文件获得登录数据,并转换成json格式,用于区块链的登录 + public String getLoginJsonStringForBlock(String username,String password) { + JSONObject jsonObject = new JSONObject(); + String commandString = "Login"; + String type ="user-act"; + String time ="1238237238723287378"; + String userNameString = username; + String passWordString = password; + String prefix ="/"+userNameString; + if (userNameString == null || passWordString == null) { +// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/ + Alert alert = new Alert(AlertType.WARNING); + alert.setTitle("UserName or Password is null"); + alert.setHeaderText("Please correct UserName or Password."); + alert.setContentText("Please correct UserName or Password."); + alert.showAndWait(); + }else{ + // 保存登录信息到本地 +// keepLoginInfo(true,userNameString,passWordString); + } + // 对密码进行哈希加密 + passWordString= EncryptionUtil.getMD5String(passWordString); + mainApp.loginer.setUserName(userNameString); + mainApp.loginer.setPassWord(passWordString); + try { + jsonObject.put("Type", type); + jsonObject.put("Command", commandString); + jsonObject.put("Prefix", prefix); + jsonObject.put("Password", passWordString); + jsonObject.put("Timestamp", time); + } catch (Exception e) { + System.out.println("exception: " + e.getMessage()); + } + return jsonObject.toString(); + } + // 从前端界面获得登录数据并转换成json格式 // 增加aesKey字段,然后将整个json用rsa公钥加密 + // 用于OA后台的登录 private String getLoginJsonRSAString() throws Exception { JSONObject jsonObject = new JSONObject(); String commandString = "/login"; String userNameString = userNameFiled.getText().trim(); + userNameString = UtilByWgh.Base64PlusEncode(userNameString) ; String passWordString = passwordFiled.getText().trim(); if (userNameString == null || passWordString == null) { // 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/ diff --git a/src/main/java/cn/minoa/view/login/NDNBlockChainConnectClient.java b/src/main/java/cn/minoa/view/login/NDNBlockChainConnectClient.java index f6a0aa1..39be698 100644 --- a/src/main/java/cn/minoa/view/login/NDNBlockChainConnectClient.java +++ b/src/main/java/cn/minoa/view/login/NDNBlockChainConnectClient.java @@ -3,11 +3,12 @@ package cn.minoa.view.login; import cn.minoa.MainApp; import cn.minoa.dataRequestInterface.KeyManager; +import javafx.scene.control.Alert; +import net.named_data.jndn.Face; +import net.named_data.jndn.Interest; import net.named_data.jndn.Name; -import net.named_data.jndn.Signature; -import net.named_data.jndn.encoding.der.DerDecodingException; +import net.named_data.jndn.encoding.EncodingException; import net.named_data.jndn.security.KeyChain; -import net.named_data.jndn.security.SecurityException; import net.named_data.jndn.security.SigningInfo; import net.named_data.jndn.security.pib.PibImpl; import net.named_data.jndn.security.tpm.TpmBackEnd; @@ -21,43 +22,56 @@ import java.io.*; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -import java.security.Security; -import java.security.cert.Certificate; + +//import org.json.XMLSerializer; +//import com.alibaba.fastjson.JSONObject; +//import net.sf.json.JSONObject; public class NDNBlockChainConnectClient { private String NDNBlockChainIPAddress; private Integer NDNBlockChainPortAddress; + private String massage=null; + private String loginmessage=null; + private int seq=1; - public NDNBlockChainConnectClient(){ - this.NDNBlockChainIPAddress= MainApp.NDNBlockChainIPAddress; - System.out.println("区块链IP:"+MainApp.NDNBlockChainIPAddress); - this.NDNBlockChainPortAddress=MainApp.NDNBlockChainPortAddress; - System.out.println("区块链Port:"+MainApp.NDNBlockChainPortAddress); + public void setMassage(String massage) { + massage = massage; } - public NDNBlockChainConnectClient(String ipAddress,Integer portAddress){ - this.NDNBlockChainIPAddress= ipAddress; - this.NDNBlockChainPortAddress=portAddress; + public void setLoginmessage(String loginmessage) { + loginmessage = loginmessage; + } + + public NDNBlockChainConnectClient() { + this.NDNBlockChainIPAddress = MainApp.NDNBlockChainIPAddress; + System.out.println("区块链IP:" + MainApp.NDNBlockChainIPAddress); + this.NDNBlockChainPortAddress = MainApp.NDNBlockChainPortAddress; + System.out.println("区块链Port:" + MainApp.NDNBlockChainPortAddress); + } + + public NDNBlockChainConnectClient(String ipAddress, Integer portAddress) { + this.NDNBlockChainIPAddress = ipAddress; + this.NDNBlockChainPortAddress = portAddress; } // 将已在区块链后台注册成功的用户注销掉 - public String deleteUser(String username,String sig){ - String prefix="/"+username; + public String deleteUser(String username, String sig) { + String prefix = "/" + username; // 获取注册数组 - byte[] registerByte=getBlockChainDeleteBuffer(prefix,sig); - System.out.println("delete length: "+registerByte.length); + byte[] registerByte = getBlockChainDeleteBuffer(prefix, sig); + System.out.println("delete length: " + registerByte.length); // 通过TCP连接区块链后台 Socket blockchainClient; try { - blockchainClient=new Socket(NDNBlockChainIPAddress,NDNBlockChainPortAddress); + blockchainClient = new Socket(NDNBlockChainIPAddress, NDNBlockChainPortAddress); } catch (IOException e) { e.printStackTrace(); - System.out.println("连接不可达:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress); + System.out.println("连接不可达:" + NDNBlockChainIPAddress + ":" + NDNBlockChainPortAddress); return e.getMessage(); } - System.out.println("已成功建立TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress - +"; 远程主机地址:"+blockchainClient.getRemoteSocketAddress()); + System.out.println("已成功建立TCP连接:" + NDNBlockChainIPAddress + ":" + NDNBlockChainPortAddress + + "; 远程主机地址:" + blockchainClient.getRemoteSocketAddress()); try { OutputStream outToServer = blockchainClient.getOutputStream(); DataOutputStream out = new DataOutputStream(outToServer); @@ -69,25 +83,25 @@ public class NDNBlockChainConnectClient { byte[] res = new byte[4]; in.read(res); int resSize = Bytes2Int_LE(res); - System.out.println("返回值长度为:"+ resSize); + System.out.println("返回值长度为:" + resSize); res = new byte[resSize]; in.read(res); System.out.println("返回值内容为:" + new String(res, StandardCharsets.UTF_8)); - System.out.println("服务器响应: " ); + System.out.println("服务器响应: "); blockchainClient.close(); - System.out.println("已关闭此次TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress); + System.out.println("已关闭此次TCP连接:" + NDNBlockChainIPAddress + ":" + NDNBlockChainPortAddress); // System.out.println("服务器响应: " ); // 解析返回来的数据,如果是200,就返回true try { - String resString=new String(res,StandardCharsets.UTF_8); - System.out.println("resString: "+resString); - JSONObject resObject=new JSONObject(resString); - int resCode=resObject.getInt("StatusCode"); - String message=resObject.getString("Message"); - if(resCode==200){ - System.out.println("区块链销户成功:"+username); + String resString = new String(res, StandardCharsets.UTF_8); + System.out.println("resString: " + resString); + JSONObject resObject = new JSONObject(resString); + int resCode = resObject.getInt("StatusCode"); + String message = resObject.getString("Message"); + if (resCode == 200) { + System.out.println("区块链销户成功:" + username); return "true"; - }else{ + } else { return message; } } catch (JSONException e) { @@ -96,27 +110,27 @@ public class NDNBlockChainConnectClient { } } catch (IOException e) { e.printStackTrace(); - System.out.println("销户时数据交换出错:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress); + System.out.println("销户时数据交换出错:" + NDNBlockChainIPAddress + ":" + NDNBlockChainPortAddress); return e.getMessage(); } } // 添加白名单 - public String addWhiteUser(String phone){ + public String addWhiteUser(String phone) { // 获取注册数组 - byte[] registerByte=getBlockChainWhiteBuffer(phone); - System.out.println("whiteuser length: "+registerByte.length); + byte[] registerByte = getBlockChainWhiteBuffer(phone); + System.out.println("whiteuser length: " + registerByte.length); // 通过TCP连接区块链后台 Socket blockchainClient; try { - blockchainClient=new Socket(NDNBlockChainIPAddress,NDNBlockChainPortAddress); + blockchainClient = new Socket(NDNBlockChainIPAddress, NDNBlockChainPortAddress); } catch (IOException e) { e.printStackTrace(); - System.out.println("连接不可达:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress); + System.out.println("连接不可达:" + NDNBlockChainIPAddress + ":" + NDNBlockChainPortAddress); return e.getMessage(); } - System.out.println("已成功建立TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress - +"; 远程主机地址:"+blockchainClient.getRemoteSocketAddress()); + System.out.println("已成功建立TCP连接:" + NDNBlockChainIPAddress + ":" + NDNBlockChainPortAddress + + "; 远程主机地址:" + blockchainClient.getRemoteSocketAddress()); try { OutputStream outToServer = blockchainClient.getOutputStream(); DataOutputStream out = new DataOutputStream(outToServer); @@ -128,24 +142,24 @@ public class NDNBlockChainConnectClient { byte[] res = new byte[4]; in.read(res); int resSize = Bytes2Int_LE(res); - System.out.println("返回值长度为:"+ resSize); + System.out.println("返回值长度为:" + resSize); res = new byte[resSize]; in.read(res); System.out.println("返回值内容为:" + new String(res)); blockchainClient.close(); - System.out.println("已关闭此次TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress); + System.out.println("已关闭此次TCP连接:" + NDNBlockChainIPAddress + ":" + NDNBlockChainPortAddress); // System.out.println("服务器响应: " ); // 解析返回来的数据,如果是200,就返回true try { - String resString=new String(res); - System.out.println("resString: "+resString); - JSONObject resObject=new JSONObject(resString); - int resCode=resObject.getInt("StatusCode"); - String message=resObject.getString("Message"); - if(resCode==200){ - System.out.println("区块链添加白名单成功:"+phone); + String resString = new String(res); + System.out.println("resString: " + resString); + JSONObject resObject = new JSONObject(resString); + int resCode = resObject.getInt("StatusCode"); + String message = resObject.getString("Message"); + if (resCode == 200) { + System.out.println("区块链添加白名单成功:" + phone); return "true"; - }else{ + } else { return message; } } catch (JSONException e) { @@ -154,13 +168,13 @@ public class NDNBlockChainConnectClient { } } catch (IOException e) { e.printStackTrace(); - System.out.println("添加白名单时数据交换出错:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress); + System.out.println("添加白名单时数据交换出错:" + NDNBlockChainIPAddress + ":" + NDNBlockChainPortAddress); return e.getMessage(); } // return true; } - // 注册用户 + /* // 注册用户 public String registeNewUser(String username,String phone,String pubkey){ // 获取注册数组 byte[] registerByte=getBlockChainRegisterBuffer(username,phone, pubkey); @@ -217,8 +231,156 @@ public class NDNBlockChainConnectClient { System.out.println("注册时数据交换出错:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress); return e.getMessage(); } + }*/ + + // 注册用户 + // public String registeNewUser(String username, String phone, String pubkey) { + public String registeNewUser(String registerJsonstring) { + // 获取注册数组 +// byte[] registerByte = getBlockChainRegisterBuffer(username, phone, pubkey); +// System.out.println("register length: " + registerByte.length); +// String informationString=new String(registerByte,StandardCharsets.UTF_8); +// System.out.println("resString: "+informationString); + + Face face = new Face(NDNBlockChainIPAddress, NDNBlockChainPortAddress); + Interest interest = new Interest(); + Name name = new Name("/mis/register"); + name.appendSequenceNumber(seq++); + interest.setName(name); + + interest.setInterestLifetimeMilliseconds(3000); // 设置生存时间为3秒 + interest.setMustBeFresh(true); // 必须是最新鲜的数据 + + interest.setApplicationParameters(new Blob(registerJsonstring.getBytes())); + + try { + // 将兴趣包发往出去 + + face.expressInterest(interest, (interest1, data) -> { + // 处理返回数据 + //long ret = data.getContent();//返回数据 + System.out.println(data.getContent().toString()); + try { + //System.out.println(data.getContent().buf().array()); + String resString= data.getContent().toString() ;//new String(data.getContent().buf().array(),StandardCharsets.UTF_8); + + JSONObject resObject=new JSONObject(resString); + + System.out.println("the return infomation"+ resObject); + // System.exit(1); + + //int resCode = resObject.getInt("StatusCode"); + int resCode = resObject.getInt("StatusCode"); + System.out.println("the return rescode"+ resCode); + massage = resObject.getString("Message"); + System.out.println("the return message"+ massage); + if (resCode == 200) { + // System.out.println("区块链用户注册成功:" + username); + massage = "注册成功"; + } else { + System.out.println("resCode!=200:" + resCode); + //flag=false; + // return message; + } + + } catch (JSONException e) { + e.printStackTrace(); + massage = e.getMessage(); + + } + + }, (interest12) -> { + // 超时处理函数 + massage =""; + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("区块链注册失败"); + alert.setHeaderText("区块链注册失败"); + alert.setContentText("区块链处理超时\n"); + alert.showAndWait(); + }, (interest13, networkNack) -> { + // 处理无路由情况 + massage =""; + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("区块链注册失败"); + alert.setHeaderText("区块链注册失败"); + alert.setContentText("区块链无路由\n"); + alert.showAndWait(); + }); + for (int i = 0; i < 1000&&massage==null; i++) { + face.processEvents(); + Thread.sleep(5); + } + // if(flag=="") + // return "true"; + } catch (IOException | EncodingException | InterruptedException e) { + e.printStackTrace(); + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("区块链注册失败"); + alert.setHeaderText("区块链注册失败"); + alert.setContentText("连接不可达\n"); + alert.showAndWait(); + System.out.println("连接不可达:" + NDNBlockChainIPAddress + ":" + NDNBlockChainPortAddress); + massage = e.getMessage(); + } + return massage; } + // 用户登录 + public String loginNewUser(String loginJsonString) { + System.out.println("the login Json in ndn"+loginJsonString); + Face face = new Face(NDNBlockChainIPAddress, NDNBlockChainPortAddress); + Interest interest = new Interest(); + interest.setName(new Name("/mis/login")); + interest.setInterestLifetimeMilliseconds(3000); // 设置生存时间为3秒 + interest.setMustBeFresh(true); // 必须是最新鲜的数据 + interest.setApplicationParameters(new Blob(loginJsonString.getBytes())); + + try { + // 将兴趣包发往出去 + + face.expressInterest(interest, (interest1, data) -> { + // 处理返回数据 + //long ret = data.getContent();//返回数据 + System.out.println(data.getContent().toString()); + String resString= data.getContent().toString() ;//new String(data.getContent().buf().array(),StandardCharsets.UTF_8); + loginmessage = resString; + System.out.println("the return LOGIN RESTRING"+ loginmessage); + + }, (interest12) -> { + // 超时处理函数 + loginmessage=""; + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("区块链登录失败"); + alert.setHeaderText("区块链登录失败"); + alert.setContentText("区块链登录超时\n"); + alert.showAndWait(); + }, (interest13, networkNack) -> { + // 处理无路由情况 + loginmessage=""; + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("区块链登录失败"); + alert.setHeaderText("区块链登录失败"); + alert.setContentText("区块链无路由\n"); + alert.showAndWait(); + }); + for (int i = 0; i < 1000&&loginmessage==null; i++) { + face.processEvents(); + Thread.sleep(5); + } + // if(flag=="") + // return "true"; + } catch (IOException | EncodingException | InterruptedException e) { + e.printStackTrace(); + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("区块链登录失败"); + alert.setHeaderText("区块链登录失败"); + alert.setContentText("连接不可达\n"); + alert.showAndWait(); + System.out.println("连接不可达:" + NDNBlockChainIPAddress + ":" + NDNBlockChainPortAddress); + loginmessage = e.getMessage(); + } + return loginmessage; + } private byte[] getBlockChainRegisterBuffer(String username,String phone, String pubkey) { String registerString=getBlockChainRegisterJsonString(username,phone, pubkey); @@ -339,7 +501,7 @@ public class NDNBlockChainConnectClient { signingInfo.setSigningIdentity(certificateV2.getIdentity()); Blob blob= KeyManager.INSTANCE.getKeyChain().sign(byteBuffer,signingInfo); // String sig=blob.toHex(); - String sig=Common.base64Encode(blob.getImmutableArray(), false); + String sig= Common.base64Encode(blob.getImmutableArray(), false); // String sig= Common.base64Encode(signature.getSignature().getImmutableArray()); // String sig1=signature.getSignature().toHex(); System.out.println("sig: "+sig); diff --git a/src/main/java/cn/minoa/view/login/NDNBlockChainConnectClientByWefree.java b/src/main/java/cn/minoa/view/login/NDNBlockChainConnectClientByWefree.java new file mode 100644 index 0000000..f899269 --- /dev/null +++ b/src/main/java/cn/minoa/view/login/NDNBlockChainConnectClientByWefree.java @@ -0,0 +1,412 @@ +package cn.minoa.view.login; +// 与区块链建立TCP连接,发送注册请求 + +import cn.minoa.MainApp; +import cn.minoa.dataRequestInterface.KeyManager; +import net.named_data.jndn.Name; +import net.named_data.jndn.Signature; +import net.named_data.jndn.encoding.der.DerDecodingException; +import net.named_data.jndn.security.KeyChain; +import net.named_data.jndn.security.SecurityException; +import net.named_data.jndn.security.SigningInfo; +import net.named_data.jndn.security.pib.PibImpl; +import net.named_data.jndn.security.tpm.TpmBackEnd; +import net.named_data.jndn.security.v2.CertificateV2; +import net.named_data.jndn.util.Blob; +import net.named_data.jndn.util.Common; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.*; +import java.net.Socket; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.security.Security; +import java.security.cert.Certificate; + +public class NDNBlockChainConnectClientByWefree { + + private String NDNBlockChainIPAddress; + private Integer NDNBlockChainPortAddress; + + public NDNBlockChainConnectClientByWefree(){ + this.NDNBlockChainIPAddress= MainApp.NDNBlockChainIPAddress; + System.out.println("区块链IP:"+MainApp.NDNBlockChainIPAddress); + this.NDNBlockChainPortAddress=MainApp.NDNBlockChainPortAddress; + System.out.println("区块链Port:"+MainApp.NDNBlockChainPortAddress); + } + + public NDNBlockChainConnectClientByWefree(String ipAddress, Integer portAddress){ + this.NDNBlockChainIPAddress= ipAddress; + this.NDNBlockChainPortAddress=portAddress; + } + + // 将已在区块链后台注册成功的用户注销掉 + public String deleteUser(String username,String sig){ + String prefix="/"+username; + // 获取注册数组 + byte[] registerByte=getBlockChainDeleteBuffer(prefix,sig); + System.out.println("delete length: "+registerByte.length); + // 通过TCP连接区块链后台 + Socket blockchainClient; + try { + blockchainClient=new Socket(NDNBlockChainIPAddress,NDNBlockChainPortAddress); + } catch (IOException e) { + e.printStackTrace(); + System.out.println("连接不可达:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress); + return e.getMessage(); + } + System.out.println("已成功建立TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress + +"; 远程主机地址:"+blockchainClient.getRemoteSocketAddress()); + try { + OutputStream outToServer = blockchainClient.getOutputStream(); + DataOutputStream out = new DataOutputStream(outToServer); + + out.write(registerByte); + InputStream inFromServer = blockchainClient.getInputStream(); + DataInputStream in = new DataInputStream(inFromServer); + System.out.println("正在等待服务器响应..."); + byte[] res = new byte[4]; + in.read(res); + int resSize = Bytes2Int_LE(res); + System.out.println("返回值长度为:"+ resSize); + res = new byte[resSize]; + in.read(res); + System.out.println("返回值内容为:" + new String(res, StandardCharsets.UTF_8)); + System.out.println("服务器响应: " ); + blockchainClient.close(); + System.out.println("已关闭此次TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress); +// System.out.println("服务器响应: " ); + // 解析返回来的数据,如果是200,就返回true + try { + String resString=new String(res,StandardCharsets.UTF_8); + System.out.println("resString: "+resString); + JSONObject resObject=new JSONObject(resString); + int resCode=resObject.getInt("StatusCode"); + String message=resObject.getString("Message"); + if(resCode==200){ + System.out.println("区块链销户成功:"+username); + return "true"; + }else{ + return message; + } + } catch (JSONException e) { + e.printStackTrace(); + return e.getMessage(); + } + } catch (IOException e) { + e.printStackTrace(); + System.out.println("销户时数据交换出错:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress); + return e.getMessage(); + } + } + + // 添加白名单 + public String addWhiteUser(String phone){ + // 获取注册数组 + byte[] registerByte=getBlockChainWhiteBuffer(phone); + System.out.println("whiteuser length: "+registerByte.length); + // 通过TCP连接区块链后台 + Socket blockchainClient; + try { + blockchainClient=new Socket(NDNBlockChainIPAddress,NDNBlockChainPortAddress); + } catch (IOException e) { + e.printStackTrace(); + System.out.println("连接不可达:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress); + return e.getMessage(); + } + System.out.println("已成功建立TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress + +"; 远程主机地址:"+blockchainClient.getRemoteSocketAddress()); + try { + OutputStream outToServer = blockchainClient.getOutputStream(); + DataOutputStream out = new DataOutputStream(outToServer); + + out.write(registerByte); + InputStream inFromServer = blockchainClient.getInputStream(); + DataInputStream in = new DataInputStream(inFromServer); + System.out.println("正在等待服务器响应..."); + byte[] res = new byte[4]; + in.read(res); + int resSize = Bytes2Int_LE(res); + System.out.println("返回值长度为:"+ resSize); + res = new byte[resSize]; + in.read(res); + System.out.println("返回值内容为:" + new String(res)); + blockchainClient.close(); + System.out.println("已关闭此次TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress); +// System.out.println("服务器响应: " ); + // 解析返回来的数据,如果是200,就返回true + try { + String resString=new String(res); + System.out.println("resString: "+resString); + JSONObject resObject=new JSONObject(resString); + int resCode=resObject.getInt("StatusCode"); + String message=resObject.getString("Message"); + if(resCode==200){ + System.out.println("区块链添加白名单成功:"+phone); + return "true"; + }else{ + return message; + } + } catch (JSONException e) { + e.printStackTrace(); + return e.getMessage(); + } + } catch (IOException e) { + e.printStackTrace(); + System.out.println("添加白名单时数据交换出错:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress); + return e.getMessage(); + } +// return true; + } + + // 注册用户 + public String registeNewUser(String username,String phone,String pubkey){ + // 获取注册数组 + byte[] registerByte=getBlockChainRegisterBuffer(username,phone, pubkey); + System.out.println("register length: "+registerByte.length); + // 通过TCP连接区块链后台 + Socket blockchainClient; + try { + blockchainClient=new Socket(NDNBlockChainIPAddress,NDNBlockChainPortAddress); + } catch (IOException e) { + e.printStackTrace(); + System.out.println("连接不可达:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress); + return e.getMessage(); + } + System.out.println("已成功建立TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress + +"; 远程主机地址:"+blockchainClient.getRemoteSocketAddress()); + try { + OutputStream outToServer = blockchainClient.getOutputStream(); + DataOutputStream out = new DataOutputStream(outToServer); + + out.write(registerByte); + InputStream inFromServer = blockchainClient.getInputStream(); + DataInputStream in = new DataInputStream(inFromServer); + System.out.println("正在等待服务器响应..."); + byte[] res = new byte[4]; + in.read(res); + int resSize = Bytes2Int_LE(res); + System.out.println("返回值长度为:"+ resSize); + res = new byte[resSize]; + in.read(res); + System.out.println("返回值内容为:" + new String(res, StandardCharsets.UTF_8)); + System.out.println("服务器响应: " ); + blockchainClient.close(); + System.out.println("已关闭此次TCP连接:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress); +// System.out.println("服务器响应: " ); + // 解析返回来的数据,如果是200,就返回true + try { + String resString=new String(res,StandardCharsets.UTF_8); + System.out.println("resString: "+resString); + JSONObject resObject=new JSONObject(resString); + int resCode=resObject.getInt("StatusCode"); + String message=resObject.getString("Message"); + if(resCode==200){ + System.out.println("区块链注册用户成功:"+username); + return "true"; + }else{ + return message; + } + } catch (JSONException e) { + e.printStackTrace(); + return e.getMessage(); + } + } catch (IOException e) { + e.printStackTrace(); + System.out.println("注册时数据交换出错:"+NDNBlockChainIPAddress+":"+NDNBlockChainPortAddress); + return e.getMessage(); + } + } + + + private byte[] getBlockChainRegisterBuffer(String username,String phone, String pubkey) { + String registerString=getBlockChainRegisterJsonString(username,phone, pubkey); + System.out.println("json: "+registerString); + int jsonLen = registerString.getBytes(StandardCharsets.UTF_8).length; + System.out.println("json len: "+jsonLen); + byte[] registerByte=new byte[jsonLen+4]; +// System.arraycopy(intToBytesLittle(jsonLen),0, +// registerByte,0,4); + System.arraycopy(intToBytesLittle(jsonLen),0, + registerByte,0,4); + System.arraycopy(registerString.getBytes(StandardCharsets.UTF_8), + 0,registerByte,4,jsonLen); + return registerByte; + } + + private byte[] getBlockChainWhiteBuffer(String phone) { + String registerString=getBlockChainWhiteUserJsonString(phone); + System.out.println("json: "+registerString); + int jsonLen = registerString.getBytes().length; + System.out.println("json len: "+jsonLen); + byte[] registerByte=new byte[jsonLen+4]; + System.arraycopy(intToBytesLittle(jsonLen),0, + registerByte,0,4); + System.arraycopy(registerString.getBytes(StandardCharsets.UTF_8), + 0,registerByte,4,jsonLen); + return registerByte; + } + + private byte[] getBlockChainDeleteBuffer(String prefix,String sig) { + String registerString=getBlockChainDeleteUserJsonString(prefix,sig); + System.out.println("json: "+registerString); + int jsonLen = registerString.getBytes().length; + System.out.println("json len: "+jsonLen); + byte[] registerByte=new byte[jsonLen+4]; + System.arraycopy(intToBytesLittle(jsonLen),0, + registerByte,0,4); + System.arraycopy(registerString.getBytes(StandardCharsets.UTF_8), + 0,registerByte,4,jsonLen); + return registerByte; + } + + /** + * 以小端模式将int转成byte[] + * + * @param value + * @return + */ + public static byte[] intToBytesLittle(int value) { + byte[] src = new byte[4]; + src[3] = (byte) ((value >> 24) & 0xFF); + src[2] = (byte) ((value >> 16) & 0xFF); + src[1] = (byte) ((value >> 8) & 0xFF); + src[0] = (byte) (value & 0xFF); + return src; + } + + /** + * 以大端模式将int转成byte[] + * + * @param value + * @return + */ + public static byte[] intToBytesBig(int value) { + byte[] src = new byte[4]; + src[0] = (byte) ((value >> 24) & 0xFF); + src[1] = (byte) ((value >> 16) & 0xFF); + src[2] = (byte) ((value >> 8) & 0xFF); + src[3] = (byte) (value & 0xFF); + return src; + } + + /** + * 转换byte数组为int(小端) + * @return + * @note 数组长度至少为4,按小端方式转换,即传入的bytes是小端的,按这个规律组织成int + */ + public int Bytes2Int_LE(byte[] bytes){ + if(bytes.length < 4) + return -1; + int iRst = (bytes[0] & 0xFF); + iRst |= (bytes[1] & 0xFF) << 8; + iRst |= (bytes[2] & 0xFF) << 16; + iRst |= (bytes[3] & 0xFF)<< 24; + + return iRst; + } + + private String getBlockChainDeleteUserJsonString(String prefix,String sig) { + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("Type", "user-act"); + jsonObject.put("Command", "Destroy"); + jsonObject.put("Prefix",prefix); + jsonObject.put("Timestamp",""); + jsonObject.put("Sig",sig); + } catch (Exception e) { + System.out.println("exception: " + e.getMessage()); + } + return jsonObject.toString(); + } + + public static String signBuf(String prefix, CertificateV2 certificateV2){ + // 构建msg + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("Type", "user-act"); + jsonObject.put("Command", "Destroy"); + jsonObject.put("Prefix",prefix); + jsonObject.put("Timestamp",""); + } catch (Exception e) { + System.out.println("exception: " + e.getMessage()); + } + String msg=jsonObject.toString(); + ByteBuffer byteBuffer=ByteBuffer.wrap(msg.getBytes(StandardCharsets.UTF_8));// 这句是C++没有的 + try { + SigningInfo signingInfo = new SigningInfo(); + signingInfo.setSigningIdentity(certificateV2.getIdentity()); + Blob blob= KeyManager.INSTANCE.getKeyChain().sign(byteBuffer,signingInfo); +// String sig=blob.toHex(); + String sig=Common.base64Encode(blob.getImmutableArray(), false); +// String sig= Common.base64Encode(signature.getSignature().getImmutableArray()); +// String sig1=signature.getSignature().toHex(); + System.out.println("sig: "+sig); + return sig; + } catch (PibImpl.Error | KeyChain.Error | TpmBackEnd.Error e) { + e.printStackTrace(); + return ""; + } + } + + private String getBlockChainWhiteUserJsonString(String phone) { + JSONObject jsonObject = new JSONObject(); + String typeString = "whiteUser"; + String commandString = "addWhiteUser"; + String RealNameString = "王锋"; + Integer GenderInteger=0; + String IDCardString=""; + try { + jsonObject.put("Type", typeString); + jsonObject.put("Command", commandString); + jsonObject.put("RealName",RealNameString); + jsonObject.put("Phone",phone); + jsonObject.put("Gender",GenderInteger); + jsonObject.put("IDCard",IDCardString); + } catch (Exception e) { + System.out.println("exception: " + e.getMessage()); + } + return jsonObject.toString(); + } + + // 从前端界面获得登录数据并转换成json格式 + private String getBlockChainRegisterJsonString(String username,String phone, String pubkey) { + JSONObject jsonObject = new JSONObject(); + String typeString = "user-act"; + String commandString = "Registry"; + String pubkeyString = pubkey; + String prefixString="/"+username; + Integer level=0; + String timestamp=""; + String IDCard=""; + String realname=""; + String aboutMe=""; + String face=""; + String print=""; + String iris=""; + String other=""; + String sig=""; + try { + jsonObject.put("Type", typeString); + jsonObject.put("Command", commandString); + jsonObject.put("Pubkey", pubkeyString); + jsonObject.put("Prefix",prefixString); + jsonObject.put("Level",level); + jsonObject.put("Timestamp",timestamp); + jsonObject.put("Username",username); + jsonObject.put("Realname",realname); + jsonObject.put("Phone",phone); + jsonObject.put("IDcard",IDCard); + jsonObject.put("AboutMe",aboutMe); + jsonObject.put("Face",face); + jsonObject.put("Print",print); + jsonObject.put("Iris",iris); + jsonObject.put("Other",other); + jsonObject.put("Sig",sig); + } catch (Exception e) { + System.out.println("exception: " + e.getMessage()); + } + return jsonObject.toString(); + } +} diff --git a/src/main/java/cn/minoa/view/login/RSACryptoByWgh.java b/src/main/java/cn/minoa/view/login/RSACryptoByWgh.java new file mode 100644 index 0000000..b4816b4 --- /dev/null +++ b/src/main/java/cn/minoa/view/login/RSACryptoByWgh.java @@ -0,0 +1,330 @@ +package cn.minoa.view.login; + +import org.apache.commons.codec.binary.Base64; + +import javax.crypto.Cipher; +import java.io.*; +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.PublicKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.X509EncodedKeySpec; + +//import org.apache.commons.io.IOUtils; +//import org.apache.commons.*; +//import java.util.*; + +// RSA算法实现 +// 原博文:https://blog.csdn.net/super_cui/article/details/70821268 +// 字符串转公钥:https://blog.csdn.net/petib_wangwei/article/details/37601081 + +public class RSACryptoByWgh { + private final static String RSA = "RSA"; + public static PublicKey uk; + // public static PrivateKey rk=get; + + /** */ + /** + * RSA最大加密明文大小 + */ + private static final int MAX_ENCRYPT_BLOCK = 245; + + /** */ + /** + * RSA最大解密密文大小 + */ + private static final int MAX_DECRYPT_BLOCK = 128; + // 忽略首行、末行 + private static String getKey(String filename) throws IOException { + String strKeyPEM = ""; + BufferedReader br = new BufferedReader(new FileReader(filename)); + String line=br.readLine(); + String nextline=""; + while ((line = br.readLine()) != null){ + strKeyPEM+=nextline; + nextline=br.readLine(); + if(nextline!=null){ + strKeyPEM += line ; + } + } + br.close(); + return strKeyPEM; + } + + +//private static byte[] encrypt(String text, PublicKey pubRSA) throws Exception{ +// Cipher cipher = Cipher.getInstance(RSA); +// cipher.init(Cipher.ENCRYPT_MODE, pubRSA); +// return cipher.doFinal(text.getBytes()); +//} + + + // public static byte[] encryptByPublicKey(String data) throws Exception { +// byte[] keyBytes = Base64.getDecoder().decode(data); +// X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); +// KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); +// Key publicK = keyFactory.generatePublic(x509KeySpec); + public static String encrypt2(String data) { + + String filepath = "./mis_rsa_public.pem"; + File file = new File(filepath); + + + RSAPublicKey publicKey = null; + try { + publicKey = getPublicKey(file.getAbsolutePath()); + } catch (IOException e) { + e.printStackTrace(); + } catch (GeneralSecurityException e) { + e.printStackTrace(); + } + // 对数据加密 + try { + Cipher cipher = Cipher.getInstance(RSA); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes("UTF-8"), publicKey.getModulus().bitLength())); +// int inputLen = data.getBytes().length; + } catch (Exception e) { + throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e); + } + } + +// ByteArrayOutputStream out = new ByteArrayOutputStream(); +// int offSet = 0; +// byte[] cache; +// int i = 0; +// // 对数据分段加密 +// while (inputLen - offSet > 0) { +// if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { +// cache = cipher.doFinal(data.getBytes(), offSet, MAX_ENCRYPT_BLOCK); +// } else { +// cache = cipher.doFinal(data.getBytes(), offSet, inputLen - offSet); +// } +// out.write(cache, 0, cache.length); +// i++; +// offSet = i * MAX_ENCRYPT_BLOCK; +// } +// byte[] encryptedData = out.toByteArray(); +// out.close(); +// return encryptedData; +// } + private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize){ + int maxBlock = 0; + if(opmode == Cipher.DECRYPT_MODE){ + maxBlock = keySize / 8; + }else{ + maxBlock = keySize / 8 - 11; + } + ByteArrayOutputStream out = new ByteArrayOutputStream(); + int offSet = 0; + byte[] buff; + int i = 0; + try{ + while(datas.length > offSet){ + if(datas.length-offSet > maxBlock){ + buff = cipher.doFinal(datas, offSet, maxBlock); + }else{ + buff = cipher.doFinal(datas, offSet, datas.length-offSet); + } + out.write(buff, 0, buff.length); + i++; + offSet = i * maxBlock; + } + }catch(Exception e){ + throw new RuntimeException("加解密阀值为["+maxBlock+"]的数据时发生异常", e); + } + byte[] resultDatas = out.toByteArray(); + try { + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + // IOUtils.closeQuietly(out); + return resultDatas; + } + + // 加密字符串 +// public static String encrypt2(String text) { +// //使用默认公钥 +// String filepath="./ndn/mis_rsa_public.pem"; +// File file=new File(filepath); +// +// +// RSAPublicKey publicKey= null; +// try { +// publicKey = getPublicKey(file.getAbsolutePath()); +// } catch (IOException e) { +// e.printStackTrace(); +// } catch (GeneralSecurityException e) { +// e.printStackTrace(); +// } +// try { +// +// +// String restring = new String(Base64.getEncoder().encode(encryptByPublicKey(text,publicKey))); +// System.out.println("the encrypt information"+restring); +// return restring; +// +// // return new String(Base64.getEncoder().encode(encrypt(text,publicKey))); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// return null; +// } + + public static RSAPublicKey getPublicKey(String filename) throws IOException, GeneralSecurityException { + String publicKeyPEM = getKey(filename); + return getPublicKeyFromString(publicKeyPEM); + } + + public static RSAPublicKey getPublicKeyFromString(String key) throws IOException, GeneralSecurityException { + String publicKeyPEM = key; +// publicKeyPEM = publicKeyPEM.replace("-----BEGIN RSA PUBLIC KEY-----", ""); +// publicKeyPEM = publicKeyPEM.replace("-----END RSA PUBLIC KEY-----", ""); + System.out.println("size: "+publicKeyPEM.getBytes().length); + System.out.println("string: "+publicKeyPEM); +// String publicKeyPEM= "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3UIWR510Jlwk6y287DfW" + +// "WpsCxafpVr2QLeqAaR04qOaaaqXuhZbUoaxgS2HjVNje9XXiZOArLXGJLKwhfUpr" + +// "YwpSIfX6DNWhHUKcwYNca2dkzO10NXPzY7SLgDP9yYyyIV42S/QCCGZ7ku7en/Ve" + +// "R/x3CIAOchoBSt6ZRh7iGwl0s5zwVTPF3is4W+46vUECkmbi8HYRjSCEvdAqo7B9" + +// "74vNb8tCrwmhztQ3+IdImukSF5/QXMCuaUKLz9CNBZ8pUl45HruG/YxNeJXIC9MV" + +// "G1pNZ6D4pBwychwLoM16qjH8/dxZnaIvK8ru09cFNYTowBUOma8u9dpQsMD4+U8O" + +// "tQIDAQAB"; + byte[] encoded = Base64.decodeBase64(publicKeyPEM); + KeyFactory kf = KeyFactory.getInstance("RSA"); + RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(new X509EncodedKeySpec(encoded)); +// RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(new PKCS8EncodedKeySpec(encoded)); + return pubKey; + } + + +// private static PublicKey getPubKey() { +// String pubKey= "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3UIWR510Jlwk6y287DfW" + +// "WpsCxafpVr2QLeqAaR04qOaaaqXuhZbUoaxgS2HjVNje9XXiZOArLXGJLKwhfUpr" + +// "YwpSIfX6DNWhHUKcwYNca2dkzO10NXPzY7SLgDP9yYyyIV42S/QCCGZ7ku7en/Ve" + +// "R/x3CIAOchoBSt6ZRh7iGwl0s5zwVTPF3is4W+46vUECkmbi8HYRjSCEvdAqo7B9" + +// "74vNb8tCrwmhztQ3+IdImukSF5/QXMCuaUKLz9CNBZ8pUl45HruG/YxNeJXIC9MV" + +// "G1pNZ6D4pBwychwLoM16qjH8/dxZnaIvK8ru09cFNYTowBUOma8u9dpQsMD4+U8O" + +// "tQIDAQAB"; +// return getPubKey(pubKey); +// } +// +// private static PublicKey getPubKey(String pubKey) { +// PublicKey publicKey = null; +// try { +// java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec( +// Base64.getDecoder().decode(pubKey)); +// // RSA对称加密算法 +// java.security.KeyFactory keyFactory; +// keyFactory = java.security.KeyFactory.getInstance(RSA); +// // 取公钥匙对象 +// publicKey = keyFactory.generatePublic(bobPubKeySpec); +// } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { +// e.printStackTrace(); +// } +// return publicKey; +// } + + + +// public static String encrypt(String text,String pubKey) { +// //先将公钥生成出来 +// PublicKey publicKey=getPubKey(pubKey); +// try { +// return byte2hex(encrypt(text, publicKey)); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// return null; +// } + + public static String byte2hex(byte[] b) { + String hs = ""; + String stmp = ""; + for (int n = 0; n < b.length; n++) { + stmp = Integer.toHexString(b[n] & 0xFF); + if (stmp.length() == 1) + hs += ("0" + stmp); + else + hs += stmp; + } + return hs.toUpperCase(); + } + + public static byte[] hex2byte(byte[] b) { + if ((b.length % 2) != 0) + throw new IllegalArgumentException("长度不是偶数"); + + byte[] b2 = new byte[b.length / 2]; + + for (int n = 0; n < b.length; n += 2) { + String item = new String(b, n, 2); + b2[n / 2] = (byte) Integer.parseInt(item, 16); + } + return b2; + } + +// public static void generateKey() throws Exception { +// KeyPairGenerator gen = KeyPairGenerator.getInstance(RSA); +// gen.initialize(512, new SecureRandom()); +// KeyPair keyPair = gen.generateKeyPair(); +// uk = keyPair.getPublic(); +// rk = keyPair.getPrivate(); +// } + +// public final static String encrypt2(String text) { +// try { +// return byte2hex(encrypt(text, uk)); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// return null; +// } + +// public final static String decrypt(String data) { +// try { +//// System.out.println("the data is "+data); +//// System.out.println("the data byte is"+data.getBytes()); +//// // System.out.println("the data byte is-"+decrypt(data)); +//// System.out.println("the data byte is-"+Base64.getDecoder().decode(data.getBytes())); +//// return new String(Base64.getDecoder().decode(decrypt(data.getBytes()))); +// Cipher cipher = Cipher.getInstance("RSA"); +// cipher.init(Cipher.DECRYPT_MODE, rk); +// return new String(cipher.doFinal(org.apache.commons.codec.binary.Base64.decodeBase64(data)), "UTF-8"); +// +// // return new String(Base64.getDecoder().decode(decrypt(hex2byte(data.getBytes())))); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// return null; +// } + +// private static byte[] decrypt(byte[] src) throws Exception { +// Cipher cipher = Cipher.getInstance(RSA); +// cipher.init(Cipher.DECRYPT_MODE, rk); +// return cipher.doFinal(src); +// } + + + + + + //just for test +// public static void main(String args[]) { +// try { +// // RSACrypto.generateKey(); +//// String filepath="D:\\wefree\\MIN-VPN\\src\\main\\java\\cn\\minoa\\view\\login\\mis_rsa_pubic.pem";//注意filepath的内容; +//// String filepath="./ndn/mis_rsa_public.pem"; +//// File file=new File(filepath); +//// uk=getPublicKey(file.getAbsolutePath()); +//// uk=getPublicKey("D:\\wefree\\MIN-VPN\\src\\main\\java\\cn\\minoa\\view\\login\\mis_rsa_pubic.pem"); +// String cipherText = RSACrypto.encrypt2("123456"); +// System.out.println("密文是:" + cipherText); +// // String plainText = RSACrypto.decrypt(cipherText); +// // System.out.println("明文是:" + plainText); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +} +// diff --git a/src/main/java/cn/minoa/view/login/RegisterOverviewController.java b/src/main/java/cn/minoa/view/login/RegisterOverviewController.java index 354e215..4ff9db0 100644 --- a/src/main/java/cn/minoa/view/login/RegisterOverviewController.java +++ b/src/main/java/cn/minoa/view/login/RegisterOverviewController.java @@ -5,10 +5,7 @@ import cn.minoa.dataRequestInterface.KeyManager; import cn.minoa.dataRequestInterface.MinoaDataAPI; import cn.minoa.dataRequestInterface.OrderInfo; import cn.minoa.dataRequestInterface.ResponseData; -import cn.minoa.util.EncryptionUtil; -import cn.minoa.util.KeyStorageUtil; -import cn.minoa.util.RegisterUtil; -import cn.minoa.util.StringByteLengthUtil; +import cn.minoa.util.*; import javafx.fxml.FXML; import javafx.scene.control.Alert; import javafx.scene.control.PasswordField; @@ -16,24 +13,18 @@ import javafx.scene.control.TextField; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.stage.Stage; -import net.named_data.jndn.Interest; import net.named_data.jndn.Name; -import net.named_data.jndn.Signature; import net.named_data.jndn.security.KeyChain; import net.named_data.jndn.security.SecurityException; -import net.named_data.jndn.security.SigningInfo; import net.named_data.jndn.security.pib.Pib; import net.named_data.jndn.security.pib.PibImpl; import net.named_data.jndn.security.tpm.Tpm; import net.named_data.jndn.security.tpm.TpmBackEnd; import net.named_data.jndn.security.v2.CertificateV2; import net.named_data.jndn.util.Common; -import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import java.nio.ByteBuffer; - public class RegisterOverviewController { @SuppressWarnings("unused") @@ -63,8 +54,9 @@ public class RegisterOverviewController { miniLogo.setImage(new Image("file:resources/images/logo_mini.png")); nickname.setPromptText("请输入一个系统新昵称..."); phoneNumber.setPromptText("请输入白名单中的手机号..."); - verifyCode.setPromptText("预留功能,不需要输入。"); - verifyCode.setDisable(true); +// verifyCode.setPromptText("预留功能,不需要输入。"); + verifyCode.setPromptText("请输入邀请码..."); +// verifyCode.setDisable(true); } // 提交表单 @@ -73,6 +65,15 @@ public class RegisterOverviewController { if (isRightContent()) { // 先拿到用户名,并修改keyChainNameString String username=nickname.getText().trim(); + username = UtilByWgh.Base64PlusEncode(username); + if(username.equals("")) { + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle("注册失败"); + alert.setHeaderText("注册账号失败"); + alert.setContentText("用户名编码错误,试试换个用户名"); + alert.showAndWait(); + return ; + } String keyChainNameString="/"+username; // 请求数据 OrderInfo orderInfo = new OrderInfo(); @@ -98,37 +99,68 @@ public class RegisterOverviewController { alert.showAndWait(); return ; } + String registerJsonString = getRegisterJsonString(publicKey,username ); + System.out.println("the registerjson string is "+registerJsonString); // 标志该用户是否已经通过了区块链注册 boolean b_flag=RegisterUtil.isAccessedBlockUser(keyChainNameString); + b_flag=true; // 如果没有注册成功过,向区块链发送注册信息;否则,跳过区块链注册 if(!b_flag) { + String pubkey = publicKey; String phonenumber = phoneNumber.getText().trim(); NDNBlockChainConnectClient ndnBlockChainConnectClient = new NDNBlockChainConnectClient(); - String resString = ndnBlockChainConnectClient.registeNewUser(username, - phonenumber, pubkey); - if (resString.equals("true")) { - System.out.println("用户【" + username + "】在区块链后台被成功注册"); +// String resString = ndnBlockChainConnectClient.registeNewUser(username, +// phonenumber, pubkey); + String resString = ndnBlockChainConnectClient.registeNewUser(RSACryptoByWgh.encrypt2(registerJsonString)); + System.out.println("the return register information "+resString); + if (resString.equals("注册成功")) { + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle("区块链注册成功"); + alert.setHeaderText("区块链注册成功"); + alert.setContentText("区块链反馈信息:\n" + resString + +"\n 请等待十秒,待区块链同步信息成功后,自动进行后续注册操作..."); + alert.showAndWait(); + dialogStage.close(); + + InstallTool.hasRegiste = true ; } else { // 区块链没有注册用户成功,则删掉刚刚生成的密钥文件 - try { - KeyManager.INSTANCE.getKeyChain().deleteIdentity(new Name(keyChainNameString)); - System.out.println("已删除本地密钥:"+keyChainNameString); - } catch (SecurityException e) { - e.printStackTrace(); - } +// try { +// KeyManager.INSTANCE.getKeyChain().deleteIdentity(new Name(keyChainNameString)); +// System.out.println("已删除本地密钥:"+keyChainNameString); +// } catch (SecurityException e) { +// e.printStackTrace(); +// } System.out.println("区块链后台注册用户【" + username + "】失败: " + resString); - // 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/ - Alert alert = new Alert(Alert.AlertType.ERROR); - alert.setTitle("区块链注册失败"); - alert.setHeaderText("区块链注册失败"); - alert.setContentText("失败原因:\n" + resString+"\n" - +"请确保你输入的手机号在系统白名单中,且用户名并没有被注册过。\n " + - "您可以将用户名适当复杂化,以保证其在系统中的唯一性。"); - alert.showAndWait(); + if(resString.length() > 0){ + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("区块链注册失败"); + alert.setHeaderText("区块链注册失败"); + alert.setContentText("失败原因:\n" + resString+"\n"); + alert.showAndWait(); + } return; } } + // 等待三秒 + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + // 向区块链发送登录信息 + LoginOverviewController lgcache=new LoginOverviewController(); + String passwordString=passwordField1.getText().trim(); + String loginStringForNDNBlock=lgcache.getLoginJsonStringForBlock(username,passwordString); + if(!lgcache.checkPassNDNBlock(loginStringForNDNBlock)){ + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("区块链登录失败"); + alert.setHeaderText("区块链登录失败"); + alert.setContentText("失败原因:\n 区块链登录失败" + "\n"); + alert.showAndWait(); + return; + } // 获取注册时JSON String registerJson=getRegisterJson(publicKey); orderInfo.setJsonString(registerJson); @@ -162,17 +194,17 @@ public class RegisterOverviewController { alert.setHeaderText("注册发送成功"); alert.setContentText("你已成功注册一个账号。"); alert.showAndWait(); - dialogStage.close(); +// dialogStage.close(); } else { - // 后台没有注册用户成功,则删掉刚刚生成的密钥文件 - try { - KeyManager.INSTANCE.getKeyChain().deleteIdentity(new Name(keyChainNameString)); - System.out.println("已删除本地密钥:"+keyChainNameString); - } catch (SecurityException e) { - e.printStackTrace(); - } - // 将该用户(区块链注册成功,后台注册失败)的注册前缀,保存到本地 - RegisterUtil.setAccessedBlockUser(keyChainNameString); +// // 后台没有注册用户成功,则删掉刚刚生成的密钥文件 +// try { +// KeyManager.INSTANCE.getKeyChain().deleteIdentity(new Name(keyChainNameString)); +// System.out.println("已删除本地密钥:"+keyChainNameString); +// } catch (SecurityException e) { +// e.printStackTrace(); +// } +// // 将该用户(区块链注册成功,后台注册失败)的注册前缀,保存到本地 +// RegisterUtil.setAccessedBlockUser(keyChainNameString); // 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/ Alert alert = new Alert(Alert.AlertType.WARNING); alert.setTitle("注册失败"); @@ -184,6 +216,65 @@ public class RegisterOverviewController { } } + //注册转Json格式 + private String getRegisterJsonString(String pubkey, String username ) { + JSONObject jsonObject = new JSONObject(); + String commandString = "Registry"; + String type = "user-act"; + String userNameString = username; + String phonnumber = phoneNumber.getText().trim(); + String Password = passwordField1.getText().trim(); + String prefix ="/"+userNameString; + String time ="4343545656565656565656"; + String realname =""; + String IDcard= ""; + String AbouMe= ""; + String Face= ""; + String Print= ""; + String Other= ""; + String Sig=""; + String action = verifyCode.getText().trim(); + if (userNameString == null || Password == null) { +// 弹窗参考:https://code.makery.ch/blog/javafx-dialogs-official/ + Alert alert = new Alert(Alert.AlertType.WARNING); + alert.setTitle("注册失败"); + alert.setHeaderText("注册失败"); + alert.setContentText("用户名或密码都不能为空"); + alert.showAndWait(); + }else{ + // 保存登录信息到本地 +// keepLoginInfo(true,userNameString,passWordString); + } + // 对密码进行哈希加密 + Password= EncryptionUtil.getMD5String(Password); + + MainApp.loginer.setUserName(userNameString); + MainApp.loginer.setPassWord(Password); + try { + jsonObject.put("Type", type); + jsonObject.put("Command", commandString); + jsonObject.put("Pubkey", pubkey); + jsonObject.put("Prefix", prefix); + jsonObject.put("Level", 0); + jsonObject.put("Timestamp", time); + jsonObject.put("Username", userNameString); + jsonObject.put("Realname", realname); + jsonObject.put("Phone", phonnumber); + jsonObject.put("IDcard", IDcard); + jsonObject.put("AboutMe", AbouMe); + jsonObject.put("Face", Face); + jsonObject.put("Print",Print); + jsonObject.put("Iris", Password); + jsonObject.put("Other", Other); + jsonObject.put("Sig", Sig); + jsonObject.put("Action", action) ; + + } catch (Exception e) { + System.out.println("exception: " + e.getMessage()); + } + return jsonObject.toString(); + } + // 将注册用户成功之前的所有通知状态修改为已阅 //【目的是减少注册后第一次登录时由于getNews到通知而反复请求通知数据带来的卡顿】 //【后台机制不是使用任何接口拿到通知都会变成已阅,而只能getNews可以这样,所以出此下策】 @@ -335,6 +426,8 @@ public class RegisterOverviewController { String commandString = "/register"; String userNameString = nickname.getText().trim(); String passWordString = passwordField1.getText().trim(); + // 对用户名进行处理 + userNameString=UtilByWgh.Base64PlusEncode(userNameString); // 对密码进行加密 passWordString= EncryptionUtil.getMD5String(passWordString); String phoneString = phoneNumber.getText().trim(); @@ -349,7 +442,16 @@ public class RegisterOverviewController { } catch (Exception e) { System.out.println("exception: " + e.getMessage()); } - return jsonObject.toString(); + String jsonString=jsonObject.toString(); + System.out.println("rsa加密前:" + jsonString); + String rsaString = null; + try { + rsaString = Rsa.encrypt(jsonString); + } catch (Exception e) { + e.printStackTrace(); + } + System.out.println("rsa加密后:" + rsaString); + return rsaString; } // 验证输入内容格式 diff --git a/src/main/java/cn/minoa/view/login/UtilByWgh.java b/src/main/java/cn/minoa/view/login/UtilByWgh.java new file mode 100644 index 0000000..22703f8 --- /dev/null +++ b/src/main/java/cn/minoa/view/login/UtilByWgh.java @@ -0,0 +1,17 @@ +package cn.minoa.view.login; + +import java.io.UnsupportedEncodingException; +import java.util.Base64; + +public class UtilByWgh { + public static String Base64PlusEncode(String srcStr){ + String dstStr = "" ; + try { + dstStr = Base64.getMimeEncoder().encodeToString(srcStr.getBytes("utf-8")); + } catch (UnsupportedEncodingException e) { + return dstStr ; + } + dstStr = dstStr.replaceAll("=","-").replaceAll("/","_") ; + return dstStr; + } +} diff --git a/src/main/java/cn/minoa/view/login/testRegister.java b/src/main/java/cn/minoa/view/login/testRegister.java index 4b19712..8f74db3 100644 --- a/src/main/java/cn/minoa/view/login/testRegister.java +++ b/src/main/java/cn/minoa/view/login/testRegister.java @@ -3,12 +3,13 @@ package cn.minoa.view.login; public class testRegister { public static void main(String[] args){ // String pubkey = "Bv0CIgcvCAVsbGFhYQgDS0VZCAhyVwiW+kaX7QgMY2VydC1yZXF1ZXN0CAn9AAABcSP8KDIUCRgBAhkEAiVRABX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAEgCbgPaAk0RRziBAW/beuF5fBQdJdbZhtKrT+FRdXq6sqPxvhM3VQF+WrBehiA5TsKpLzwzNoE8kKt8gyevM4dxZHGwEDHBgHFggFbGxhYWEIA0tFWQgIclcIlvpGl+39AP0m/QD+DzIwMjAwMzI5VDAxNTEwMf0A/w8yMDIwMDQwOFQwMTUxMDAXSDBGAiEApxH8lJntSBM/NwV+laSdifH674+76xZnxVF4vKGaXXkCIQCj3OyzagvjqYrJmZ9f00PWVISXRyrIrKmwFbwzsk/hQw=="; - NDNBlockChainConnectClient ndnBlockChainConnectClient=new NDNBlockChainConnectClient("116.77.74.139",9001); + NDNBlockChainConnectClient ndnBlockChainConnectClient= + new NDNBlockChainConnectClient("121.15.171.91",6363); // String res=ndnBlockChainConnectClient.registeNewUser("wf001", // "003",pubkey); // System.out.println("添加白名单结果:"+res); - for(Integer i=21;i<=30;i++){ - String res=ndnBlockChainConnectClient.addWhiteUser("3"+i); + for(Integer i=11;i<=20;i++){ + String res=ndnBlockChainConnectClient.addWhiteUser("1"+i); System.out.println("添加白名单结果:"+res); } // String res_del=ndnBlockChainConnectClient.deleteUser("test_0416v2",""); diff --git a/src/main/resources/fxml/login/RegisterOverview.fxml b/src/main/resources/fxml/login/RegisterOverview.fxml index fd7d955..cbda6a8 100644 --- a/src/main/resources/fxml/login/RegisterOverview.fxml +++ b/src/main/resources/fxml/login/RegisterOverview.fxml @@ -20,9 +20,9 @@ - + - + @@ -39,10 +39,10 @@