diff --git a/src/main/java/com/sunyard/SydApiException.java b/src/main/java/com/sunyard/SydApiException.java index a8b103f..51cd224 100644 --- a/src/main/java/com/sunyard/SydApiException.java +++ b/src/main/java/com/sunyard/SydApiException.java @@ -45,6 +45,9 @@ public class SydApiException extends RuntimeException{ case 4: msg = "DER 编码格式错误(公钥) "; break; + case 0xd: + msg = "公钥加密错误"; + break; case 21: msg = "输入的数据格式错误 "; break; diff --git a/src/main/java/racal/sunyard/main/SydApi4j.java b/src/main/java/racal/sunyard/main/SydApi4j.java index ecd48a8..5cd7f72 100644 --- a/src/main/java/racal/sunyard/main/SydApi4j.java +++ b/src/main/java/racal/sunyard/main/SydApi4j.java @@ -2587,49 +2587,69 @@ public class SydApi4j implements SydApi { private ByteBuffer read(Socket socket) throws IOException { InputStream is = socket.getInputStream(); - int d; - int high = is.read(); - int low = is.read(); - int len = (high << 8) + low; + byte[] buf = new byte[2]; + int offset = 0; + int remaining = 2; + while (remaining > 0) { + int read = is.read(buf, offset, remaining); + if (read == -1) { + throw new EOFException("Expected 2 bytes, but reached end of stream after reading " + offset + " byte(s)"); + } + offset += read; + remaining -= read; + } + int len = ((buf[0] & 0xFF) << 8) | (buf[1] & 0xFF); len += 2; if(debug){ - print("H\t"); - println(Integer.toHexString(high)); - print("L\t"); - println(Integer.toHexString(low)); - print("Len\t"); + print("接收数据\t"); +// print("H="); +// print(Integer.toHexString(high)); +// print("\tL="); +// print(Integer.toHexString(low)); + print("\tLen="); println(len); } ByteBuffer bb = ByteBuffer.allocate(len); - bb.put((byte) (high & 0xFF)); + bb.put(buf); +// bb.put((byte) (high & 0xFF)); //println(String.format("%d %d %s",len, bb.position() -1, Util.bytes2HexString(new byte[]{(byte) (high & 0xFF)}))); - bb.put((byte) (low & 0xFF)); +// bb.put((byte) (low & 0xFF)); //println(String.format("%d %d %s",len, bb.position() -1, Util.bytes2HexString(new byte[]{(byte) (low & 0xFF)}))); +// int d = 0; +// while (true) { +// d = is.read(); +// if (-1 == d) { +// break; +// } +// +// bb.put((byte) (d & 0xFF)); +// +// //println(String.format("%d %d %s",len, bb.position() -1, Util.bytes2HexString(new byte[]{(byte) (d & 0xFF)}))); +// +// if (bb.position() == len) { +// break; +// } +// } + remaining = len - bb.position(); // 还需要读取的字节数 + byte[] buffer = new byte[8192]; // 批量读取缓冲区 - while (true) { - d = is.read(); - if (-1 == d) { - break; - } - - bb.put((byte) (d & 0xFF)); - - //println(String.format("%d %d %s",len, bb.position() -1, Util.bytes2HexString(new byte[]{(byte) (d & 0xFF)}))); - - if (bb.position() == len) { - break; + while (remaining > 0) { + int toRead = Math.min(remaining, buffer.length); + int bytesRead = is.read(buffer, 0, toRead); + if (bytesRead == -1) { + // 与原逻辑不同:这里抛异常,而不是静默退出 + throw new EOFException("Unexpected end of stream; expected " + remaining + " more bytes"); } + bb.put(buffer, 0, bytesRead); + remaining -= bytesRead; } - - - if (null != builder && builder.isUseEBCDMode()) { // print("EBCD 数据: \t"); // println(Util.bytes2HexString(bb.array())); @@ -2663,8 +2683,10 @@ public class SydApi4j implements SydApi { ByteBuffer bb = read(socket); return bb; - } catch (SocketTimeoutException e) { - throw new SydApiException("接收数据超时", -2); + } catch (EOFException e) { + throw new SydApiException("接收数据不完整", -21, e); + }catch (SocketTimeoutException e) { + throw new SydApiException("接收数据超时", -2, e); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/test/java/cmbpoc/FunctionTest.java b/src/test/java/cmbpoc/FunctionTest.java index be21da2..4721d34 100644 --- a/src/test/java/cmbpoc/FunctionTest.java +++ b/src/test/java/cmbpoc/FunctionTest.java @@ -1,6 +1,8 @@ package cmbpoc; import com.sunyard.RetWrap; +import com.sunyard.SydApi; +import com.sunyard.proto.PacketSection; import com.sunyard.proto.Util; import org.junit.*; import racal.sunyard.main.SydApi4j; @@ -14,7 +16,7 @@ public class FunctionTest { private byte[] publicKey4Sign; private byte[] privateKey4Ende; private byte[] publicKey4Ende; - private byte[] orgData = new byte[2 * 1024]; + private byte[] orgData = new byte[15]; private String sign; @Before @@ -24,15 +26,19 @@ public class FunctionTest { System.setProperty("com.sunyard.sydapi4j.debug", "true"); // 建立链接(单台) - this.api = (SydApi4j) new SydApi4j().connect("172.1.41.139", 8889, null, 5000); + this.api = (SydApi4j) new SydApi4j().connect("192.168.100.145", 8889, null, 5000); - RetWrap keypair = this.getPrivateKeyAndPublickKey(keypairIndex4Sign); - this.publicKey4Sign = Util.hexString2Bytes( keypair.get("pk").toString() ); - this.privateKey4Sign = Util.hexString2Bytes( keypair.get("sk").toString() ); +// RetWrap keypair = this.getPrivateKeyAndPublickKey(keypairIndex4Sign); +// this.publicKey4Sign = Util.hexString2Bytes( keypair.get("pk").toString() ); +// this.privateKey4Sign = Util.hexString2Bytes( keypair.get("sk").toString() ); +// +// RetWrap keypair4Ende = this.getPrivateKeyAndPublickKey(keypairIndex4Sign); +// this.publicKey4Ende = Util.hexString2Bytes( keypair4Ende.get("pk").toString() ); +// this.privateKey4Ende = Util.hexString2Bytes( keypair4Ende.get("sk").toString() ); - RetWrap keypair4Ende = this.getPrivateKeyAndPublickKey(keypairIndex4Sign); - this.publicKey4Ende = Util.hexString2Bytes( keypair4Ende.get("pk").toString() ); - this.privateKey4Ende = Util.hexString2Bytes( keypair4Ende.get("sk").toString() ); + + this.publicKey4Ende = Util.hexString2Bytes("03420004AF3D4E55D26564C6C937E6EA9232691C01AC5E7916AD2136F788CE7C1E4D0AE8C4754DEC2F7F6A78962D51A171A6F5B4F11823390AEC8B5B0246CD2CCF8052B7"); + this.privateKey4Ende = Util.hexString2Bytes("00010000963F7C3A98B7810F52D2861A060E18A9D4D59796CF33967DD61EEDA091E1AD9B0000000000000000000000000000000000000000000000000000000000000000"); } @@ -49,15 +55,21 @@ public class FunctionTest { @Ignore @Test public void genKeyPair(){ - RetWrap r = this.api.SYD_SM2GenKeyPair(); - String pk = r.get("publicKey").toString(); - String sk = r.get("privateKey").toString(); +// RetWrap r = this.api.SYD_SM2GenKeyPair(); +// String pk = r.get("publicKey").toString(); +// String sk = r.get("privateKey").toString(); +// +// System.out.println("pk=" + pk); +// System.out.println("sk=" + sk); +// +// this.privateKey4Sign = Util.hexString2Bytes(sk); +// this.publicKey4Sign = Util.hexString2Bytes(pk); - System.out.println("pk=" + pk); - System.out.println("sk=" + sk); - - this.privateKey4Sign = Util.hexString2Bytes(sk); - this.publicKey4Sign = Util.hexString2Bytes(pk); + RetWrap rw = this.api.SM2GenKeyPair(); + byte[] pk = (byte[]) rw.get(SydApi.RET_PUBLIC_KEY); + byte[] sk = (byte[]) rw.get(SydApi.RET_PRIVATE_KEY); + System.out.println("pk=" + Util.bytes2HexString(pk)); + System.out.println("sk=" + Util.bytes2HexString(sk)); } @@ -86,8 +98,10 @@ public class FunctionTest { @Test public void SYD_SM2_Encrypt(){ - byte[] enData = this.api.SYD_SM2Encrypt(privateKey4Ende, orgData); + byte[] enData = this.api.SYD_SM2Encrypt(publicKey4Ende, orgData); // byte[] deData = this.api.SYD_SM2Decrypt(publicKey4Ende, enData); // Assert.assertArrayEquals(enData, deData); } -} \ No newline at end of file +} + +