From aa2761b10ec7dc73b7b7577f44bd4c6836186578 Mon Sep 17 00:00:00 2001 From: ChessNineeee <709030194@qq.com> Date: Tue, 6 Apr 2021 14:37:22 +0800 Subject: [PATCH 1/2] db and internal's implementation --- .../identity/persist/sqlite/db/Db.java | 114 +++++++++++++++--- 1 file changed, 98 insertions(+), 16 deletions(-) diff --git a/src/main/java/minsecurity/identity/persist/sqlite/db/Db.java b/src/main/java/minsecurity/identity/persist/sqlite/db/Db.java index 0043580..b39e543 100644 --- a/src/main/java/minsecurity/identity/persist/sqlite/db/Db.java +++ b/src/main/java/minsecurity/identity/persist/sqlite/db/Db.java @@ -15,11 +15,13 @@ import java.util.ArrayList; import java.util.Base64; import java.util.List; + public final class Db { private static Identity getIdentityByNameFromStorage(String name, Connection c) throws Exception { - Statement stmt = c.createStatement(); - ResultSet rs = stmt.executeQuery(String.format("SELECT * FROM identityinfo WHERE name = %s LIMIT 1", name)); // LIMIT 1代替Queryrow - stmt.close(); + PreparedStatement pstmt = c.prepareStatement("SELECT * FROM identityinfo WHERE name = ? LIMIT 1");// LIMIT 1代替Queryrow + pstmt.setString(1, name); + ResultSet rs = pstmt.executeQuery(); + pstmt.close(); return getIdentityFromSqlRow(rs); } @@ -86,7 +88,7 @@ public final class Db { } private static Identity getDefaultIdentityFromStorage(ResultSet rs) throws Exception{ - if (rs == null) + if (!rs.isBeforeFirst()) return null; String pubStr = "", priStr = "", pass = "", certStr = "", name = "", prikeyRawByte = ""; @@ -116,20 +118,18 @@ public final class Db { } - private static boolean setDefaultIdentityFromStorage(String name, Connection c) throws Exception{ + private static void setDefaultIdentityFromStorage(String name, Connection c) throws Exception{ PreparedStatement stmt = c.prepareStatement("update identityinfo set is_default = 1 where name= ?"); stmt.setString(1, name); stmt.executeUpdate(); stmt.close(); - return true; } - private static boolean cancelDefaultIdentityFromStorage(String name, Connection c) throws Exception{ + private static void cancelDefaultIdentityFromStorage(String name, Connection c) throws Exception{ PreparedStatement stmt = c.prepareStatement("update identityinfo set is_default = 0 where name= ?"); stmt.setString(1, name); stmt.executeUpdate(); stmt.close(); - return true; } public static List getAllIdentityFromStorage(String name) throws Exception { @@ -148,23 +148,105 @@ public final class Db { return getIdentityByNameFromStorage(name, c); } - private static boolean setDefaultIdentityByNameInStorage(String name) throws Exception { + private static void setDefaultIdentityByNameInStorage(String name) throws Exception { Connection c = Sqlite.getInstance().getConn(); - return false; + c.setAutoCommit(false); + try{ + PreparedStatement pstmt = c.prepareStatement("select * from identityinfo where name = ? LIMIT 1"); + pstmt.setString(1, name); + ResultSet rs = pstmt.executeQuery(String.format("select * from identityinfo where name = %s LIMIT 1", name)); + getDefaultIdentityFromStorage(rs); + pstmt.close(); + + PreparedStatement pstmt2 = c.prepareStatement("SELECT * from identityinfo where is_default = ?"); + pstmt2.setInt(1, 1); + rs = pstmt2.executeQuery(); + Identity id = getDefaultIdentityFromStorage(rs); + if (id != null){ + cancelDefaultIdentityFromStorage(id.getName(), c); + } + setDefaultIdentityFromStorage(name, c); + pstmt2.close(); + c.commit(); + c.close(); + }catch (Exception ex){ + System.out.println(ex.getMessage()); + c.rollback(); + c.close(); + throw ex; + } } - public static boolean SetDefaultIdentityByNameInStorage(String name) throws Exception { + + public static void SetDefaultIdentityByNameInStorage(String name) throws Exception { for (int i = 0; i < 4; i++){ - boolean res = false; try{ - res = setDefaultIdentityByNameInStorage(name); - return res; + setDefaultIdentityByNameInStorage(name); + return; }catch (Exception ex){ + if (i == 3) + return; if (ex.getMessage().equals("database is locked")) Thread.sleep(50); else - return false; + throw ex; } } - return false; + } + + public static void deleteIdentityByName(String name) throws Exception{ + Connection c = Sqlite.getInstance().getConn(); + PreparedStatement pstmt = c.prepareStatement("elete from identityinfo where name=?"); + pstmt.setString(1, name); + pstmt.executeUpdate(); + pstmt.close(); + c.close(); + } + + public static void persistIdentity(Identity identity) throws Exception{ + Identity id = getIdentityByNameFromStorage(identity.getName()); + if (id != null) + throw new Exception("The name has existed"); + + Connection c = Sqlite.getInstance().getConn(); + String pubStr = "", priStr = "", certStr, prikeyRawByte = ""; + int algo, sign; + if (identity.hasPrivateKey()){ + byte[] priByte = identity.getPrikey().getBytes(); + priStr = Base64.getEncoder().encodeToString(priByte); + } + if (identity.getPubkey() != null){ + byte[] pubByte = identity.getPubkey().getBytes(); + pubStr = Base64.getEncoder().encodeToString(pubByte); + } + + algo = identity.getKeyParam().PublicKeyAlgorithm; + sign = identity.getKeyParam().SignatureAlgorithm; + + certStr = CertUtils.toPem(identity.getCert(), null, Common.SM4ECB); + + if (identity.getPrikeyRawByte() != null) + prikeyRawByte = Base64.getEncoder().encodeToString(identity.getPrikeyRawByte()); + + PreparedStatement pstmt = c.prepareStatement("INSERT INTO identityinfo(name, pubkey, prikey, pubkey_algo, signature_algo, pass, cert,prikey_raw_byte) values(?,?,?,?,?,?,?,?)"); + pstmt.setString(1, identity.getName()); + pstmt.setString(2, priStr); + pstmt.setString(3, pubStr); + pstmt.setInt(4, algo); + pstmt.setInt(5, sign); + pstmt.setString(6, identity.getPasswd()); + pstmt.setString(7, certStr); + pstmt.setString(8, prikeyRawByte); + + pstmt.executeUpdate(); + pstmt.close(); + c.close(); + } + + public Identity getDefaultIdentityFromStorage() throws Exception{ + Connection c = Sqlite.getInstance().getConn(); + PreparedStatement pstmt = c.prepareStatement("SELECT * from identityinfo where is_default= ? LIMIT 1"); + pstmt.setInt(1, 1); + ResultSet rs = pstmt.executeQuery(); + return getDefaultIdentityFromStorage(rs); } } From f6da0c30ba74800d07e94e385c6a895f669c2a26 Mon Sep 17 00:00:00 2001 From: ChessNineeee <709030194@qq.com> Date: Tue, 6 Apr 2021 23:16:50 +0800 Subject: [PATCH 2/2] change the driver which is compatible with sqlcipher and modified the way to connect the encrypted sqlite db file --- pom.xml | 11 ++++-- .../identity/persist/sqlite/Sqlite.java | 18 +++++++--- .../identity/persist/sqlite/db/Db.java | 1 + .../identity/sqlite/SqliteTest.java | 35 +++++++++++++++++++ .../identity/sqlite/db/DBTest.java | 4 +++ 5 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 src/test/java/minsecurity/identity/sqlite/db/DBTest.java diff --git a/pom.xml b/pom.xml index 7dfa890..0f59b56 100644 --- a/pom.xml +++ b/pom.xml @@ -94,12 +94,17 @@ 3.0.8 - + + + + + + - org.xerial + io.github.willena sqlite-jdbc - 3.28.0 + 3.35.4 diff --git a/src/main/java/minsecurity/identity/persist/sqlite/Sqlite.java b/src/main/java/minsecurity/identity/persist/sqlite/Sqlite.java index cd4d468..6a50d25 100644 --- a/src/main/java/minsecurity/identity/persist/sqlite/Sqlite.java +++ b/src/main/java/minsecurity/identity/persist/sqlite/Sqlite.java @@ -1,5 +1,8 @@ package minsecurity.identity.persist.sqlite; +import org.sqlite.mc.SQLiteMCConfig; +import org.sqlite.mc.SQLiteMCSqlCipherConfig; + import java.io.File; import java.sql.*; @@ -34,6 +37,10 @@ public class Sqlite { } + private String passwd2HexKey(){ + return String.format("x'%s'", passwd); + } + /** * 获取Sqlite object * @return Sqlite object @@ -70,8 +77,8 @@ public class Sqlite { new File(dbPath).mkdirs(); } String real_db_file = dbPath + db_file; - Class.forName("org.sqlite.JDBC"); - c = DriverManager.getConnection("jdbc:sqlite:" + real_db_file); + // 兼容sqlcipher + c = DriverManager.getConnection("jdbc:sqlite:" + real_db_file, SQLiteMCSqlCipherConfig.getV4Defaults().withKey(passwd2HexKey()).toProperties()); stmt = c.createStatement(); stmt.executeUpdate(table_create); stmt.close(); @@ -92,8 +99,8 @@ public class Sqlite { new File(filePath).mkdirs(); } String real_db_file = filePath + db_file; - Class.forName("org.sqlite.JDBC"); - c = DriverManager.getConnection("jdbc:sqlite:" + real_db_file); + // 兼容sqlcipher + c = DriverManager.getConnection("jdbc:sqlite:" + real_db_file, SQLiteMCSqlCipherConfig.getV4Defaults().withKey(passwd2HexKey()).toProperties()); stmt = c.createStatement(); stmt.executeUpdate(table_create); stmt.close(); @@ -111,7 +118,8 @@ public class Sqlite { try{ String real_db_file = db_path + db_file; Class.forName("org.sqlite.JDBC"); - c = DriverManager.getConnection("jdbc:sqlite:" + real_db_file); + // 兼容sqlcipher + c = DriverManager.getConnection("jdbc:sqlite:" + real_db_file, SQLiteMCSqlCipherConfig.getV4Defaults().withKey(passwd2HexKey()).toProperties()); // TODO 设置数据库最大连接数 return c; }catch (Exception ex){ diff --git a/src/main/java/minsecurity/identity/persist/sqlite/db/Db.java b/src/main/java/minsecurity/identity/persist/sqlite/db/Db.java index b39e543..d028be6 100644 --- a/src/main/java/minsecurity/identity/persist/sqlite/db/Db.java +++ b/src/main/java/minsecurity/identity/persist/sqlite/db/Db.java @@ -210,6 +210,7 @@ public final class Db { Connection c = Sqlite.getInstance().getConn(); String pubStr = "", priStr = "", certStr, prikeyRawByte = ""; int algo, sign; + if (identity.hasPrivateKey()){ byte[] priByte = identity.getPrikey().getBytes(); priStr = Base64.getEncoder().encodeToString(priByte); diff --git a/src/test/java/minsecurity/identity/sqlite/SqliteTest.java b/src/test/java/minsecurity/identity/sqlite/SqliteTest.java index 8f2f170..2aca043 100644 --- a/src/test/java/minsecurity/identity/sqlite/SqliteTest.java +++ b/src/test/java/minsecurity/identity/sqlite/SqliteTest.java @@ -1,5 +1,6 @@ package minsecurity.identity.sqlite; +import minsecurity.identity.persist.sqlite.Sqlite; import minsecurity.identity.persist.sqlite.SqliteUtil; import org.junit.Test; @@ -11,4 +12,38 @@ public class SqliteTest { System.out.println(SqliteUtil.home()); assertFalse(SqliteUtil.pathExists("/aaa/1.txt")); } + + @Test + public void TestSqliteOpen(){ + try{ + Sqlite.getInstance().openDefault(); + boolean res = SqliteUtil.pathExists("/home/zhengqi/min/identity/identity.db"); + if (!res){ + throw new Exception("no target db file!!"); + } + + String homePath = SqliteUtil.home(); + String filePath = homePath + "/test/"; + Sqlite.getInstance().open(filePath); + + boolean res1 = SqliteUtil.pathExists("/home/zhengqi/test/identity.db"); + if (!res1){ + throw new Exception("no target db file!!"); + } + }catch (Exception ex){ + System.out.println(ex.getMessage()); + } + } + + @Test + public void TestSqliteSetPasswd(){ + try{ + String newPasswd = "1DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99"; + Sqlite.getInstance().setPasswd(newPasswd); + Sqlite.getInstance().open("/home/zhengqi/min/identity/"); + // Sqlite.getInstance().getConn(); + }catch (Exception ex){ + System.out.println(ex.getMessage()); + } + } } diff --git a/src/test/java/minsecurity/identity/sqlite/db/DBTest.java b/src/test/java/minsecurity/identity/sqlite/db/DBTest.java new file mode 100644 index 0000000..e9109b5 --- /dev/null +++ b/src/test/java/minsecurity/identity/sqlite/db/DBTest.java @@ -0,0 +1,4 @@ +package minsecurity.identity.sqlite.db; + +public class DBTest { +}