`
litxuf
  • 浏览: 122508 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

DSA签名在java与.net平台的互联互通问题

阅读更多

        最近在弄DSA签名的工作,本以为很简单的事情 但却因为客户是 .net的开发环境而产生的很多麻烦的事情

在查看了相关文档尤其是 徐某人的 (http://archive.cnblogs.com/a/1687902/)这篇文章之后,有了很大的启发并得到了如下的解决方案!

        我们先来看DER编码规则

    DSA签名产生得到的是r和s两个整数。对于DSAWithSHA1来说,这两个整数都不会超过20字节。由于DSA签名需要使用一个随机数,所以每次签名的结果是不同的。

JAVA产生的DSAWithSHA1的签名结果是个下面ASN.1结构的DER编码:

Dss-Sig-Value  ::=  SEQUENCE  {

r       INTEGER,

s       INTEGER  }

.NET要求的签名结果40字节,前面20字节是r,后面20字节是s,采用大端字节序。

DER编码采用TLV的形式,每种类型有个Tag的编码,是为T部分的编码,接着是长度的编码,是为L部分的编码,最后是内容的编码,是为V部分的编码。

对于SEQUENCE来说,Tag的编码为0x30,其内容编码就是其容纳的ASN.1对象的逐个TLV编码拼起来。

对于INTEGER来说,Tag的编码为0x02,其内容编码就是使用最小的字节进行的补码形式。前9位不能全为1或者全为0。最高位为0表示正数,最高位为1表示负数。由于这里都是正数,所以如果最高位为1的话,前面要补0,也就是说最长的整数内容部分的编码长度为20+1=21字节。

长度的编码对于不超过127的来说,只占有一个字节,编码就是值本身。这里就是这种情况。

例子说明:

Java的签名

30 2C

02 14

1C FA 3A BB 5C 0F 37 FB D7 74 CB 51 E5 64 B5 76 B9 26 4F 7A

02 14

62 7E FF 2D 11 4B 2D D3 27 F3 8B 30 D1 6D B4 D2 78 5A 72 5B

30表示是SEQUENCE

2C表示后面编码有0x2c字节

02表示是INTEGER

14表示后面编码有0x14字节

1C FA 3A BB 5C 0F 37 FB D7 74 CB 51 E5 64 B5 76 B9 26 4F 7A这部分就是r内容的编码

这里r内容的编码刚好是20自己,直接拷贝即可。如果小于20字节,则前面补0到20字节。如果是21字节,则去掉最前面的1个字节,这个字节应该是0,表示r是正数;如果这个字节不是0则签名是错的。

02 表示是INTEGER

14表示后面编码有0x14字节

62 7E FF 2D 11 4B 2D D3 27 F3 8B 30 D1 6D B4 D2 78 5A 72 5B这部分是s内容的编码。处理方式和r内容的编码一样。

最后转换得到.NET的签名为

1C FA 3A BB 5C 0F 37 FB D7 74 CB 51 E5 64 B5 76 B9 26 4F 7A 62 7E FF 2D 11 4B 2D D3 27 F3 8B 30 D1 6D B4 D2 78 5A 72 5B

  以上文字来自徐某人的博客的文章

      java平台生成的DSA签名有45,46,47,48等几种而.net平台只能是40位 这时候就需要他们的相互转化了 

 length=45

48 43

 2 19 

 94 116 4 99 101 -21 -74 83 89 -78 50 25 28 12 95 50 22 -8 83 

2 20 

  120 85 -101 -40 27 123 57 -55 -7 -124 119 -13 67 -106 -106 119 95 64 61 -15 


 length=46
48 44 
2 20 
38 7 -93 -28 -103 111 105 -59 -75 -70 -43 26 63 75 -121 75 -97 -102 -90 -92 
2 20 
104 66 -83 22 -38 12 69 -6 -44 46 57 81 -37 47 -88 126 -121 104 -88 50  

 length=47

48 45 
2 21 
 0 -106 -47 -114 -27 -22 103 14 37 16 -119 -91 -123 14 19 -112 -105 -77 -28 57 4 
2 20
 46 -68 -40 45 -57 -126 25 103 -44 91 92 108 -28 40 5 54 -10 11 -61 -10 

 length=48

48 46 
2 21 
 0 -117 25 28 49 -117 2 -115 -13 -31 2 49 35 -64 -39 109 -76 107 14 -25 7
2 21
 0 -120 122 114 -56 -6 84 13 -19 41 95 -68 29 -53 63 -98 -56 -113 -96 28 -53

通过分析 发现如下 规律
1. 46位是标准格式 前四位是 48 44 2 20 第25和26位 是 2 ,20
   20代表后面的字节个数 .net 只需截取 5-24 和 27-46 这40位的数字即可
2.45 位是因为前段或后端的数据有一个是19位 转成 .net 前面加零补齐即可 
3. 47位是因为有组数据为21位 去掉那组数据的开始的第一位数据 即可
4. 48位是因为有两组数据为21位 去掉那组数据的开始的第一位数据 即可

转化代码如下:
 public static byte[] changeDSANet2java(String sign) {

byte tx[] = decryptBASE64(sign);

byte[] tx_new = new byte[46];
tx_new[0] = 48;
tx_new[1] = 44;
tx_new[2] = 2;
tx_new[3] = 20;

for (int x = 0; x < 20; x++) {
tx_new[x + 4] = tx[x];
}
tx_new[24] = 2;
tx_new[25] = 20;

for (int x = 20; x < 40; x++) {
tx_new[x + 6] = tx[x];
}
return tx_new;

}


分享到:
评论
1 楼 litxuf 2011-06-13  
------------------ 可恶的64k 2w汉字 ---------------
接上
-------------------------------------------------------


public static byte[] changeDSAJava2net(byte[] Content) {
byte[] RByte = new byte[40];
// byte[] SByte = new byte[20];
// byte[] Content = DERStr.getBytes();

int IntRLength = Content[3];
int j = 0;
// 第一段是 20个字符
if (IntRLength == 20) {
for (int i = 0; i < 20; i++) {
RByte[i] = Content[4 + i];
}
j = 24;
} else if (IntRLength > 20) {
// 第五位数字是0
for (int i = 0; i < 20; i++) {
RByte[i] = Content[5 + i];
}
j = 25;
} else {
// IntRLength 19 NotEnough 1
int NotEnough = 20 - IntRLength;
for (int i = 0; i < NotEnough; i++) {
// 不足数据用0补齐
RByte[i] = 0;
}
for (int i = 0; i < IntRLength; i++) {
RByte[NotEnough + i] = Content[4 + i];
}
j = 24 - NotEnough;
}

int IntSLength = Content[j + 1];
if (IntSLength == 20) {
for (int i = 0; i < 20; i++) {
RByte[i + 20] = Content[j + 2 + i];
}
} else if (IntSLength > 20) {
for (int i = 0; i < 20; i++) {
RByte[i + 20] = Content[j + 3 + i];
}
} else {
int NotEnough = 20 - IntSLength;
for (int i = 0; i < NotEnough; i++) {
RByte[i + 20] = 0;
}
for (int i = 0; i < IntSLength; i++) {
RByte[NotEnough + i + 20] = Content[j + 2 + i];
}
}
return RByte;
}

网上关于DSA的签名的实现代码很多 在此不再赘述 有疑问可以去问问百度或google
再次感谢徐某人!

相关推荐

    DSA签名算法的Java实现

    这个文件可能包含了上述Java代码的实现,或者是用于演示如何在Java中与其他语言(如C或C++)交互进行DSA签名的示例。这通常涉及到序列化和反序列化密钥和签名,以及可能的跨语言的兼容性问题。 DSA签名算法的Java...

    DSA数字签名 DSA数字签名

    DSA数字签 DSA数字签DSA数字签名 DSA数字签名

    DSA签名算法的C#实现

    DSA(Digital Signature Algorithm)是一种基于离散对数问题的公钥密码学算法,常用于数字签名,以确保数据的完整性和发送者的身份。在C#中实现DSA签名算法,主要涉及以下几个关键步骤和知识点: 1. **密钥生成**:...

    DSA.rar_DSA数字签名_DSA算法_dsa_java dsa_数字签名

    总结起来,DSA数字签名在Java中的实现涉及了密钥对生成、签名生成与验证等步骤,这些步骤都是通过`java.security`包中的类和方法完成的。了解并掌握这些知识点,对于开发安全的网络应用程序至关重要。同时,通过阅读...

    .net DSA加密(C#读取OPENSSL生成的DSA的pem文件的秘钥)

    .NET框架中的DSA(Digital Signature Algorithm,数字签名算法)是一种基于离散对数问题的公钥加密算法,常用于数字签名和认证。在本资源中,我们关注的是如何使用C#来处理OpenSSL生成的PEM格式的DSA密钥。PEM...

    rsa-elgamal-dsa.rar_DSA算法_ELGAMAL_dsa_dsa签名算法_elgamal java

    在Java中,`java.security.Signature`类提供了DSA签名功能,通过`Signature.getInstance("DSA")`创建实例,然后分别调用`initSign`和`initVerify`进行签名和验证操作。 2. ELGamal加密算法: ELGamal是由 Taher ...

    DSA.zip_DSA C数字签名_DSA 签名_DSA签名_dsa_dsa 数字签名

    **DSA(Digital Signature Algorithm)**是一种基于离散对数问题的公钥密码体制,由美国国家标准与技术研究院(NIST)在1991年提出,主要用于数字签名,确保数据的完整性和来源的不可否认性。 **数字签名**是密码学...

    dsa.rar_DSA C数字签名_DSA签名_dsa_dsa 数字签名_数字签名DSA

    **DSA(Digital Signature Algorithm)是数字签名领域中一种广泛应用的算法,主要基于离散对数问题的难度。它由美国国家标准与技术研究所(NIST)在1991年提出,目的是为了提供一个公开可验证的安全签名算法。DSA...

    DSA_Java.zip_DSA java_algorithms_dsa

    标题 "DSA_Java.zip_DSA java_algorithms_dsa" 暗示了这个压缩包包含的是与Java编程语言相关的数字签名算法(Digital Signature Algorithm,简称DSA)实现。DSA是一种广泛使用的公钥密码学算法,主要用于数据签名和...

    dsa数字签名算法的验证及实现

    在本主题中,我们将深入探讨“dsa(Digital Signature Algorithm,数字签名算法)”的验证和实现,这是一个广泛应用于电子商务、软件发布和其他需要安全通信场景的技术。 DSA是由美国国家安全局(NSA)设计,并在...

    数字签名实验.zip_DSA 签名_DSA签名_c 数字签名_zjz_实验数字签名

    DSA签名程序和DSA验证程序。 签名程序流程: a. 读入字符串(从屏幕或文本文件中),字符串内容应包含自己的学号或姓名; b. 计算该字符串的SHA-1值; c. 生成DSA密钥对(利用dsa_make_key); d. 利用dsa_export...

    ASP.NET中数字签名的实现

    在ASP.NET中,数字签名是一种确保数据完整性和来源可靠性的技术,它对于网络安全至关重要。本文将深入探讨如何在ASP.NET中实现数字签名,以及涉及到的相关概念如哈希散列。 首先,我们来理解数字签名的基本原理。...

    DSA.zip_DSA C数字签名_DSA数字签名_DSA签名_c 数字签名_数字签名

    **DSA(Digital Signature Algorithm)**是一种基于离散对数问题的公钥密码体制,由美国国家标准与技术研究所(NIST)在1991年制定,主要用于数字签名,确保数据的完整性和来源的真实性。 **一、DSA签名原理** DSA...

    md5.zip_DSA C数字签名_DSA 签名_DSA实现_Stankiewicz_dsa 数字签名

    《深入理解DSA数字签名:C语言实现与SHA哈希算法》 数字签名是现代密码学中的重要组成部分,它在确保信息安全传输、防止篡改和伪造等方面发挥着关键作用。DSA(Digital Signature Algorithm)是由美国国家标准和...

    DSA数字签名例子

    在电子通信和互联网交易中,DSA数字签名被广泛用于确保数据的完整性和发送者的身份验证。 DSA的核心原理是利用非对称加密技术,即每个用户有一对密钥,一个是私钥,仅由用户自己保管,用于签名;另一个是公钥,可以...

    C#.NET 安全编程 实例 RSA DSA 对称 非对称 加密 解密 XML 数字签名

    在C#.NET编程环境中,安全性和加密技术是至关重要的,特别是在处理敏感数据和网络通信时。本主题将深入探讨RSA和DSA两种非对称加密算法,以及对称加密的概念,同时涉及XML数字签名的实现。 首先,让我们了解对称...

    BM算法+DES算法+DSA签名

    C++以其高效性和灵活性被选择用于实现BM算法和DES加密,而Java由于其跨平台的特性以及丰富的安全库,成为实现DSA签名的理想选择。在提供的压缩包文件中,可能包含了这三个算法的C++和Java源代码实现,这对于学习和...

    dsa2.1_dsa_签名算法_

    DSA,全称为Digital Signature Algorithm(数字签名算法),是基于离散对数问题的非对称加密算法,主要用于数据签名,确保信息的完整性和发送者的身份验证。在信息安全领域,DSA被广泛应用于电子文档的签名、软件的...

    Java 数字签名和验证

    在Java中,我们可以使用内置的Java Cryptography Extension (JCE)库来实现RSA、DSA和ECC这三种不同的签名算法。下面将详细阐述这些概念以及如何在Java中实现它们。 首先,我们要理解什么是数字签名。数字签名并非...

    java AES,DES,3DES,RAS,DSA 加密算法实现

    Java的`java.security.Signature`类提供了DSA的实现,如`Signature.getInstance("SHA256withDSA")`用于生成或验证DSA签名。 在Java中实现这些加密算法时,通常需要进行以下步骤: 1. 导入相关包,如`javax.crypto`...

Global site tag (gtag.js) - Google Analytics