- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在将头撞到加密的砖墙上之后,我今天来找你,手里拿着帽子。
前提是:我有一个 python 脚本,可以生成 ASN.1 编码的 DER key 。然后,我有另一个 python 脚本,它采用 DER 私钥并使用它来解密 Base64 编码的字符串。我目前正在尝试将第二个脚本转换为其 C# 替代方案,并且在某种程度上我已经让它工作了。
使用原始Python脚本时,解密后的输出长度为127字节,而我拥有的C#代码长度为16字节。此时,我认为我的 C# 代码完全错误,直到我注意到 python 输出和 C# 输出的最后 16 个字节完全相同。什么?
这是我的 prosterity 代码(显然没有错误检查等)
输入 DER 私钥(针对网络的 Base64 编码)
MIICXAIBAAKBgQDMJQczcaoGepZIPcTGJB5AfSBFqhCt5B+HRpaUosZzAhooljxKrlRd3oLww2pqyjyGl9bqrKhaRuCPaEg/RHYvqT3gEjtW9XrF3absMP2ihp+SgOTnRaQLlK7Wyh2QU4XKTd0Pyjv+nYTM3R1LRveN2YEg+dWUeGqGJuNs9NArqwIDAQABAoGBAMT0kI78gbrAeM938Knt3NYBIqqzmmX6qsR7wPnkVaxOAejYkZDHwpPSAujA0KH5Pg3o3qwJKl/2897IELQhnBdCfb1AvL87ENj0Kh1+SP5Y2LeqQVRE3HT1fGXlbBDdXDiCNiBcgnIT7nsVKA+KmKUjJI/MvefM9p2sVJudVfdxAkEA+6GtJqjOF4Ver/O+J8LJF5O0/fh6MRvdHKqPNehm+NygtAxsygu1MTpZFJVAHsfdQnL+rRJi9vbqiwHfNbsVmQJBAM+wTmCHhJ7g3RAGswhbgAqg3LfM8dre03b4fwHkp4+S6j5tcYazrN8dqifiL83Hyo0522BQsRt+YADIk7f1TeMCQFhEXWW7Pxf3G8Di4mg2Jq4TjSCtocdKO+TLW5MQY9aWJfUiiqLROoz7J7ZVqHljqJSfnAB/+6Ef+iQq0u6ZIrkCQGDELZBuM81uybD43hurvjm1f4EnvRwULATHfS2dorCTbA6QIY/4UThXcvtIOKuxRd+NMHhswEgmFobm7WSNp68CQEMn75sLC874hitiqVVu6bNyDsOG4X6Cyc8uLKA58BeIg8eG590ehrFHYR0JsawgePsAVXb/RCPuYgONi5TRHBk=
输入加密字符串(Base64 编码)
e1algxNK5vfiLQmN42bQf9CHJnRGH06w13P+ObHx5U7XJWbCsh9HKclXX88b2peEG4U3K4WC+dSNGLEPe8d3bPwxlBOYXVgsAHKLrgD7gXJDOG+gMawUsUlVx+hWPESITHXDscbcM6zASUuIWGtPkJw3r00MwJy9ZzYqfr2OiJg=
使用 (PyCrypt) 解码加密字符串的 Python RSA 脚本
//removed python code to convert base64 encoded DER key to ASN.1 and then to RSA key tuple for pycrypto, the following is the hex data within the tuple:
key = ['0x0:0xcc:0x25:0x7:0x33:0x71:0xaa:0x6:0x7a:0x96:0x48:0x3d:0xc4:0xc6:0x24:0x1e:0x40:0x7d:0x20:0x45:0xaa:0x10:0xad:0xe4:0x1f:0x87:0x46:0x96:0x94:0xa2:0xc6:0x73:0x2:0x1a:0x28:0x96:0x3c:0x4a:0xae:0x54:0x5d:0xde:0x82:0xf0:0xc3:0x6a:0x6a:0xca:0x3c:0x86:0x97:0xd6:0xea:0xac:0xa8:0x5a:0x46:0xe0:0x8f:0x68:0x48:0x3f:0x44:0x76:0x2f:0xa9:0x3d:0xe0:0x12:0x3b:0x56:0xf5:0x7a:0xc5:0xdd:0xa6:0xec:0x30:0xfd:0xa2:0x86:0x9f:0x92:0x80:0xe4:0xe7:0x45:0xa4:0xb:0x94:0xae:0xd6:0xca:0x1d:0x90:0x53:0x85:0xca:0x4d:0xdd:0xf:0xca:0x3b:0xfe:0x9d:0x84:0xcc:0xdd:0x1d:0x4b:0x46:0xf7:0x8d:0xd9:0x81:0x20:0xf9:0xd5:0x94:0x78:0x6a:0x86:0x26:0xe3:0x6c:0xf4:0xd0:0x2b:0xab',
'0x1:0x0:0x1',
'0x0:0xc4:0xf4:0x90:0x8e:0xfc:0x81:0xba:0xc0:0x78:0xcf:0x77:0xf0:0xa9:0xed:0xdc:0xd6:0x1:0x22:0xaa:0xb3:0x9a:0x65:0xfa:0xaa:0xc4:0x7b:0xc0:0xf9:0xe4:0x55:0xac:0x4e:0x1:0xe8:0xd8:0x91:0x90:0xc7:0xc2:0x93:0xd2:0x2:0xe8:0xc0:0xd0:0xa1:0xf9:0x3e:0xd:0xe8:0xde:0xac:0x9:0x2a:0x5f:0xf6:0xf3:0xde:0xc8:0x10:0xb4:0x21:0x9c:0x17:0x42:0x7d:0xbd:0x40:0xbc:0xbf:0x3b:0x10:0xd8:0xf4:0x2a:0x1d:0x7e:0x48:0xfe:0x58:0xd8:0xb7:0xaa:0x41:0x54:0x44:0xdc:0x74:0xf5:0x7c:0x65:0xe5:0x6c:0x10:0xdd:0x5c:0x38:0x82:0x36:0x20:0x5c:0x82:0x72:0x13:0xee:0x7b:0x15:0x28:0xf:0x8a:0x98:0xa5:0x23:0x24:0x8f:0xcc:0xbd:0xe7:0xcc:0xf6:0x9d:0xac:0x54:0x9b:0x9d:0x55:0xf7:0x71']
// from https://www.dlitz.net/software/pycrypto/api/current/Crypto.PublicKey.RSA-module.html
// from Crypto.PublicKey import RSA
rsa = RSA.construct(key)
plain_text = RSA.decrypt(cipher_text.decode('base64'))
Python 脚本输出
0x02:0x96:0xd3:0x80:0xeb:0xcc:0x89:0xa1:0xff:0x0f:0x97:0x64:0x21:0x6b:0xf1:0x69:0xe3:0xa9:0xb7:0x5a:0x7e:0xd8:0xe8:0x2d:0xa9:0x27:0x78:0x90:0x8a:0x56:0x58:0xcd:0x4a:0x08:0x24:0x22:0xdd:0x88:0xa0:0x58:0xe1:0x18:0xd2:0xe4:0xca:0xa3:0xba:0x70:0xa7:0x6d:0x07:0x40:0x9e:0x2a:0x23:0x05:0x73:0x5e:0x23:0xb3:0x0c:0xa8:0xb4:0x43:0xf8:0xee:0xa6:0x67:0xfb:0x56:0xb0:0xcc:0x59:0xe3:0x59:0x9b:0xe5:0x9c:0xae:0xca:0x3f:0x17:0x73:0xf8:0x69:0x1b:0x73:0x20:0xfe:0x2a:0x0d:0x91:0x8f:0x94:0x26:0xde:0x3c:0xdb:0xa2:0x3e:0xf9:0x8f:0x0d:0x8c:0xd2:0x7b:0xfb:0xd6:0x92:0x8c:0x00:0x11:0x5c:0x31:0x5e:0xee:0x76:0xfe:0xf5:0x4a:0x9e:0x04:0x51:0x8a:0x3d:0x93:0xec
C# RSA解密脚本
static void Main(string[] args)
{
var derContent = Convert.FromBase64String(base64DerContent); //base64DerContent is the "Input DER Private Key" above
var rsa = DecodeRSAPrivateKey(derContent);
Byte[] cipher_text_data = Convert.FromBase64String("e1algxNK5vfiLQmN42bQf9CHJnRGH06w13P+ObHx5U7XJWbCsh9HKclXX88b2peEG4U3K4WC+dSNGLEPe8d3bPwxlBOYXVgsAHKLrgD7gXJDOG+gMawUsUlVx+hWPESITHXDscbcM6zASUuIWGtPkJw3r00MwJy9ZzYqfr2OiJg=");
Byte[] raw = rsa.Decrypt(cipher_text_data, false);
string hex = BitConverter.ToString(raw);
System.Console.WriteLine("Decrypted: " + hex);
}
//the following code taken from http://www.jensign.com/opensslkey/opensslkey.cs
//------- Parses binary ans.1 RSA private key; returns RSACryptoServiceProvider ---
public static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
{
byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
// --------- Set up stream to decode the asn.1 encoded RSA private key ------
MemoryStream mem = new MemoryStream(privkey);
BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading
byte bt = 0;
ushort twobytes = 0;
int elems = 0;
try
{
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
binr.ReadByte(); //advance 1 byte
else if (twobytes == 0x8230)
binr.ReadInt16(); //advance 2 bytes
else
return null;
twobytes = binr.ReadUInt16();
if (twobytes != 0x0102) //version number
return null;
bt = binr.ReadByte();
if (bt != 0x00)
return null;
//------ all private key components are Integer sequences ----
elems = GetIntegerSize(binr);
MODULUS = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
E = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
D = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
P = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
Q = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
DP = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
DQ = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
IQ = binr.ReadBytes(elems);
System.Console.WriteLine("showing components ..");
if (true)
{
System.Console.WriteLine("\nModulus", MODULUS);
System.Console.WriteLine("\nExponent", E);
System.Console.WriteLine("\nD", D);
System.Console.WriteLine("\nP", P);
System.Console.WriteLine("\nQ", Q);
System.Console.WriteLine("\nDP", DP);
System.Console.WriteLine("\nDQ", DQ);
System.Console.WriteLine("\nIQ", IQ);
}
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSAParameters RSAparams = new RSAParameters();
RSAparams.Modulus = MODULUS;
RSAparams.Exponent = E;
RSAparams.D = D;
RSAparams.P = P;
RSAparams.Q = Q;
RSAparams.DP = DP;
RSAparams.DQ = DQ;
RSAparams.InverseQ = IQ;
RSA.ImportParameters(RSAparams);
return RSA;
}
catch (Exception)
{
return null;
}
finally
{
binr.Close();
}
}
private static int GetIntegerSize(BinaryReader binr)
{
byte bt = 0;
byte lowbyte = 0x00;
byte highbyte = 0x00;
int count = 0;
bt = binr.ReadByte();
if (bt != 0x02) //expect integer
return 0;
bt = binr.ReadByte();
if (bt == 0x81)
count = binr.ReadByte(); // data size in next byte
else
if (bt == 0x82)
{
highbyte = binr.ReadByte(); // data size in next 2 bytes
lowbyte = binr.ReadByte();
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
count = BitConverter.ToInt32(modint, 0);
}
else
{
count = bt; // we already have the data size
}
while (binr.ReadByte() == 0x00)
{ //remove high order zeros in data
count -= 1;
}
binr.BaseStream.Seek(-1, SeekOrigin.Current); //last ReadByte wasn't a removed zero, so back up a byte
return count;
}
C# 脚本输出
11-5C-31-5E-EE-76-FE-F5-4A-9E-04-51-8A-3D-93-EC
正如您所看到的,C# 代码的输出只有 16 个字节长,但它直接匹配 python 脚本的最后 16 个字节。我不确定到底发生了什么,我对 RSA 的(基本)理解告诉我它应该是一个全有或全无的函数——整个文本都会被解密,否则我就会得到乱码。
最佳答案
这里的问题是填充。 RSA 操作要求在加密之前使用安全填充方案来填充消息。否则,存在某些可以恢复私钥的攻击。这是一篇很好的文章解释why .
出于某种原因,Python 加密库不会为您删除填充,但 C# 库会。因此,您必须在 Python 代码中手动删除填充。
幸运的是,从您提供的数据来看,这里使用的填充方案似乎是 PKCS#1.5。这是一个相对简单的填充方案,很容易处理。完整的规范位于 RFC 3447 中,但归结为:
EM = 0x00 || 0x02 || PS || 0x00 || M.
其中EM
是加密前填充的消息,PS
是填充,M
是原始的、未填充的消息。
这是一个可以为您完成这项工作的 Python 函数:
def RemovePKCS15Padding( padded_msg ):
if len(padded_msg) < 2 or padded_msg[0]!='\x02':
raise PaddingError # or whatever
p = padded_msg.find('\x00')
if p < 0:
raise PaddingError # or whatever
return padded_msg[p+1:]
关于c# - 将Python RSA解密脚本转换为C#,输出仅是最后16B而不是128B,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18340398/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!