有人知道我将如何将java代码转换成python吗?在
/**
* signs the data for the account account
*/
private byte[] sign(String pkStr,byte[] data, String keyType) throws Exception {
BASE64Decoder decoder = new BASE64Decoder();
KeyFactory keyFac = null;
//instantiate the key factory based on the key alg type
if(keyType.equals("DSA")){
keyFac = KeyFactory.getInstance("DSA");
}else if(keyType.equals("RSA")){
keyFac = KeyFactory.getInstance("RSA");
}
//generate the public key
PKCS8EncodedKeySpec dprks = new PKCS8EncodedKeySpec(decoder.decodeBuffer(pkStr));
PrivateKey pk = keyFac.generatePrivate(dprks);
return(signBytes(data,pk,keyType));
}
/**
* sign the data with the key
*/
private byte[] signBytes(byte [] data,
PrivateKey signingPrivateKey, String keyType)throws Exception {
Signature dsa = null;
//instantiate the signature alg based on the key type
if(keyType.equals("DSA")){
dsa = Signature.getInstance("SHA1withDSA");
}else if(keyType.equals("RSA")){
dsa = Signature.getInstance("SHA1withRSA");
}
/* Initializing the object with a private key */
dsa.initSign(signingPrivateKey);
/* Update and sign the data */
dsa.update(data);
byte[] sig = dsa.sign();
return sig;
}
“keyType”似乎总是被传递为“DSA”,所以我研究了M2Crypto.DSA,这看起来很有前途。这个数字签名但是,函数返回一个由2字节字符串组成的元组,我根本不知道该如何处理。在
根据http://download.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html#AppB(出于某种奇怪的原因,它有两个附录B,您需要向下滚动到第二个),Java使用ASN.1编码
SEQUENCE ::= { r INTEGER, s INTEGER }
您应该能够使用pyasn1-http://pyasn1.sourceforge.net/在Python中生成(并解析)这个
ASN.1是二进制数据编码的标准。所以上面的信息指定了Java代码如何组合Python代码返回的两个值。因此,您可以执行相同的操作,从而为签名维护相同的字节格式。在
DSA签名被定义为一对整数(分别称为r和s)。DSA standard不强制将此类签名的特定编码转换为字节序列。因此,使用DSA签名的每个协议都必须定义自己的编码。在
有两种常用的DSA签名编码;一种是直接串联r和s值的大端无符号编码,它们都规范化为公钥中的q参数的长度(以字节为单位)(“子组大小”,通常是一个160位素数整数,从而产生一个40字节的签名)。M2文件加密DSA非常简洁,但我猜它会分别返回r和s,但已经是这种格式了。在
Java使用另一种基于ASN.1的编码。这是贯穿X.509和基于它的任何东西(包括SSL/TLS中的签名)使用的编码。ASN.1是结构化数据表示和序列化的通用标准。在这种情况下,签名应该是包含两个
INTEGER
值的ASN.1SEQUENCE
的序列化(按顺序为r和s)。根据ASN.1和DER编码规则,签名应具有以下格式:0x30A0x02B R0x02C S
其中:
R是最小长度的大端有符号编码:这意味着第一个字节的值应该在0到127之间,只有第二个字节的值在128到255之间时,它才有值0。换句话说,将r编码为big-endian约定的字节序列(最重要的字节排在第一位),确保您有尽可能少的前导零位,前提是您至少保留一位(这就是“有符号”编码的意思:因为r是正的,它的最高有效位必须是0)。由于r是一个介于0和q-1之间的整数,r的长度最多比q的长度多1个字节,但可以更小。
S是S的大端有符号编码(与r的处理相同;注:r和S可能有不同的长度)。
B是包含R长度的单个字节(以字节为单位)。
C是包含S长度的单个字节(以字节为单位)。
A是包含B+C+2的单个字节(即字节A后面的长度)。
为基于ASN.1的DSA签名编写专门的编码和解码函数有点乏味,但并不困难;只需注意生成大小合适的R和S序列。或者,您也可以使用现有的ASN.1编码/解码库,这是一种过激的做法,但可能更容易,具体取决于您的情况。在
相关问题 更多 >
编程相关推荐