起初我以为是填充,因为 mcrypt 使用零填充,但我将 php 更改为使用 PKCS7 并获得相同的精确结果
有人可以帮忙吗?我认为这与 php 中的填充有关
.Net 的测试输出:
Key: d88f92e4fa27f6d45b49446c7fc76976
Text: Testing123
Encrypted: /DMkj7BL9Eu2LMxKhdGT+A==
Encrypted after base64 decode: ?3$??K?K?,?J???
Decrypted: Testing123
PHP 的测试输出:
Key: d88f92e4fa27f6d45b49446c7fc76976
Text: Testing123
Encrypted: K+ke5FNI5T6F6B/XvDF494+S8538Ze83cFz6v1FE89U=
Encrypted after base64 decode: +éäSHå>…è×¼1x÷’óüeï7p\ú¿QDóÕ
Decrypted: Testing123����������������������
PHP:
class rijndael{
var $mcrypt_cipher = MCRYPT_RIJNDAEL_256;
var $mcrypt_mode = MCRYPT_MODE_CBC;
function decrypt($pass, $encrypted)
{
$encrypted = base64_decode($encrypted);
$key = $this->getkey($pass);
$iv = $this->getiv($pass);
$decrypted = mcrypt_decrypt($this->mcrypt_cipher, $key, $encrypted, $this->mcrypt_mode, $iv);
$block = mcrypt_get_block_size($this->mcrypt_cipher, $this->mcrypt_mode);
$pad = ord($decrypted[($len = strlen($decrypted)) - 1]);
return substr($decrypted, 0, strlen($decrypted) - $pad);
}
function encrypt($pass, $decrypted)
{
$key = $this->getkey($pass);
$iv = $this->getiv($pass);
$block = mcrypt_get_block_size($this->mcrypt_cipher, $this->mcrypt_mode);
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);
$encrypted = mcrypt_encrypt($this->mcrypt_cipher, $key, $decrypted, $this->mcrypt_mode, $iv);
return base64_encode($encrypted);
}
function getkey($passphrase)
{
$L1 = base64_encode(hash("sha256", $passphrase, true));
$L2 = $passphrase.$L1;
return hash("sha256", $L2, true);
}
function getiv($passphrase)
{
$L1 = base64_encode(md5($passphrase));
$L2 = $passphrase.$L1;
return md5($L2);
}
}
VB.Net:
Public Class RijnDael
Public Shared Function Decrypt(ByVal sData As String, ByVal sKey As String)
Dim bytData() As Byte = Encoding.UTF8.GetBytes(sData)
Return Decrypt(bytData, sKey)
End Function
Public Shared Function Decrypt(ByVal bytData As Byte(), ByVal strPass As String) As Byte()
Dim bytResult As Byte()
Using oRM As New System.Security.Cryptography.RijndaelManaged
oRM.KeySize = 256
oRM.Key = GeKey(strPass)
oRM.IV = GetIV(strPass)
oRM.Mode = CipherMode.CBC
oRM.Padding = PaddingMode.PKCS7
Using oMS As New MemoryStream(bytData)
Using oCS As New Cryptography.CryptoStream(oMS, oRM.CreateDecryptor, Security.Cryptography.CryptoStreamMode.Read)
Dim TempDecryptArr As Byte()
ReDim TempDecryptArr(bytData.Length)
Dim decryptedByteCount As Integer
decryptedByteCount = oCS.Read(TempDecryptArr, 0, bytData.Length)
'
ReDim bytResult(decryptedByteCount)
Array.Copy(TempDecryptArr, bytResult, decryptedByteCount)
'
oCS.Close()
End Using
oMS.Close()
End Using
End Using
Return bytResult
End Function
Public Shared Function Encrypt(ByVal sData As String, ByVal sKey As String)
Dim bytData() As Byte = Encoding.UTF8.GetBytes(sData)
Return Encrypt(bytData, sKey)
End Function
Public Shared Function Encrypt(ByVal bytData As Byte(), ByVal strPass As String) As Byte()
Dim bytResult As Byte()
Using oRM As New Cryptography.RijndaelManaged
oRM.KeySize = 256
oRM.Key = GeKey(strPass)
oRM.IV = GetIV(strPass)
oRM.Mode = CipherMode.CBC
oRM.Padding = PaddingMode.PKCS7
Using oMS As New MemoryStream
Using oCS As New Cryptography.CryptoStream(oMS, oRM.CreateEncryptor, Cryptography.CryptoStreamMode.Write)
oCS.Write(bytData, 0, bytData.Length)
oCS.FlushFinalBlock()
bytResult = oMS.ToArray()
oCS.Close()
End Using
oMS.Close()
End Using
End Using
Return bytResult
End Function
Private Shared Function GeKey(ByVal strPass As String) As Byte()
Dim bytResult As Byte()
'Generate a byte array of required length as the encryption key.
'A SHA256 hash of the passphrase has just the required length. It is used twice in a manner of self-salting.
Using oSHA256 As New Cryptography.SHA256Managed
Dim L1 As String = System.Convert.ToBase64String(oSHA256.ComputeHash(Encoding.UTF8.GetBytes(strPass)))
Dim L2 As String = strPass & L1
bytResult = oSHA256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(L2))
oSHA256.Clear()
End Using
Return bytResult
End Function
Private Shared Function GetIV(ByVal strPass As String) As Byte()
Dim bytResult As Byte()
'Generate a byte array of required length as the iv.
'A MD5 hash of the passphrase has just the required length. It is used twice in a manner of self-salting.
Using oMD5 As New Cryptography.MD5CryptoServiceProvider
Dim L1 As String = System.Convert.ToBase64String(oMD5.ComputeHash(Encoding.UTF8.GetBytes(strPass)))
Dim L2 As String = strPass & L1
bytResult = oMD5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(L2))
oMD5.Clear()
End Using
Return bytResult
End Function
End Class
最佳答案
你的两段代码中的问题是:
在 .NET 和 PHP 代码中使用 Rijndael-128, key 和 block 大小均为 16 字节/128 位。对于 Rijndael-256,您的代码生成了一个长度错误的 IV。而且我不知道如何在 PHP 中使用 AES-256( key 长度为 32 字节/256 位, block 大小为 16 字节/128 位)。
MD5的使用:在PHP代码中,在md5()函数中添加第二个参数true(在两个地方)所以结果是二进制数据而不是十六进制字符串。
在您的 PHP 代码的 encrypt() 函数中,将变量 $str 替换为 $decrypted(在两个地方)。 $str 从未被赋值也从未被使用,因此填充无效。
如果你解决了这些问题,那么两个程序都会返回结果:
Encrypted: /DMkj7BL9Eu2LMxKhdGT+A==
我没试过解密。
关于php - .Net 和 PHP Rijndael 加密不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7387080/
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg
如何匹配未被反斜杠转义的平衡定界符对(其本身未被反斜杠转义)(无需考虑嵌套)?例如对于反引号,我试过了,但是转义的反引号没有像转义那样工作。regex=/(?!$1:"how\\"#expected"how\\`are"上面的正则表达式不考虑由反斜杠转义并位于反引号前面的反斜杠,但我愿意考虑。StackOverflow如何做到这一点?这样做的目的并不复杂。我有文档文本,其中包括内联代码的反引号,就像StackOverflow一样,我想在HTML文件中显示它,内联代码用一些spanMaterial装饰。不会有嵌套,但转义反引号或转义反斜杠可能出现在任何地方。
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
我已经在mountainlion上成功安装了rbenv和rubybuild。运行rbenvinstall1.9.3-p392结束于:校验和不匹配:ruby-1.9.3-p392.tar.gz(文件已损坏)预期f689a7b61379f83cbbed3c7077d83859,得到1cfc2ff433dbe80f8ff1a9dba2fd5636它正在下载的文件看起来没问题,如果我使用curl手动下载文件,我会得到同样不正确的校验和。有没有人遇到过这个?他们是如何解决的? 最佳答案 tl:博士;使用浏览器从http://ftp.rub
@raw_array[i]=~/[\W]/非常简单的正则表达式。当我用一些非拉丁字母(具体来说是俄语)尝试时,条件是错误的。我能用它做什么? 最佳答案 @raw_array[i]=~/[\p{L}]/使用西里尔字符进行测试。引用:http://www.regular-expressions.info/unicode.html#prop 关于ruby-正则表达式将非英文字母匹配为非单词字符,我们在StackOverflow上找到一个类似的问题: https://