Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用shell_exec()从PHP脚本调用C程序_Php_C_Hash_Web Applications_Cryptography - Fatal编程技术网

使用shell_exec()从PHP脚本调用C程序

使用shell_exec()从PHP脚本调用C程序,php,c,hash,web-applications,cryptography,Php,C,Hash,Web Applications,Cryptography,我对Web开发完全陌生,目前,我在构建登录页面时遇到了麻烦 我编写了一个PHP脚本,输入时获取用户名和密码。然后将密码作为参数发送给我编写的C程序,该程序只对密码进行散列(MD5)。这是使用以下代码完成的: $username = $_POST['uname']; $password = $_POST['passwd']; $hashvalue = shell_exec("md5.exe $password"); 现在,当我在登录表单中以1234的形式输入密码时,我得到的输出是f7d4cef

我对Web开发完全陌生,目前,我在构建登录页面时遇到了麻烦

我编写了一个PHP脚本,输入时获取用户名和密码。然后将密码作为参数发送给我编写的C程序,该程序只对密码进行散列(MD5)。这是使用以下代码完成的:

$username = $_POST['uname'];
$password = $_POST['passwd'];

$hashvalue = shell_exec("md5.exe $password");
现在,当我在登录表单中以1234的形式输入密码时,我得到的输出是f7d4cef3bfacebfc49d5574e7d9c1d6f

但是当我在单独运行C程序时使用1234作为输入时,我得到了不同的输出81dc9bdb52d04dc20036dbd8313ed055。这也是我实际应该得到的输出。正如我使用各种在线MD5哈希程序检查的那样,这些程序给出了相同的输出

在C程序中,我使用
gets()
获取输入,并使用
printf
显示输出。此外,我还使用了MySQL数据库(phpMyAdmin)

C程序代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

typedef union uwb {
    unsigned w;
    unsigned char b[4];
} MD5union;

typedef unsigned DigestArray[4];

unsigned func0( unsigned abcd[] ){
    return ( abcd[1] & abcd[2]) | (~abcd[1] & abcd[3]);}

unsigned func1( unsigned abcd[] ){
    return ( abcd[3] & abcd[1]) | (~abcd[3] & abcd[2]);}

unsigned func2( unsigned abcd[] ){
    return  abcd[1] ^ abcd[2] ^ abcd[3];}

unsigned func3( unsigned abcd[] ){
    return abcd[2] ^ (abcd[1] |~ abcd[3]);}

typedef unsigned (*DgstFctn)(unsigned a[]);



unsigned *calctable( unsigned *k)
{
    double s, pwr;
    int i;

    pwr = pow( 2, 32);
    for (i=0; i<64; i++) {
        s = fabs(sin(1+i));
        k[i] = (unsigned)( s * pwr );
    }
    return k;
}


unsigned rol( unsigned r, short N )
{
    unsigned  mask1 = (1<<N) -1;
    return ((r>>(32-N)) & mask1) | ((r<<N) & ~mask1);
}

unsigned *md5( const char *msg, int mlen)
{
    /*Initialize Digest Array as A , B, C, D */
    static DigestArray h0 = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476 };
    static DgstFctn ff[] = { &func0, &func1, &func2, &func3 };
    static short M[] = { 1, 5, 3, 7 };
    static short O[] = { 0, 1, 5, 0 };
    static short rot0[] = { 7,12,17,22};
    static short rot1[] = { 5, 9,14,20};
    static short rot2[] = { 4,11,16,23};
    static short rot3[] = { 6,10,15,21};
    static short *rots[] = {rot0, rot1, rot2, rot3 };
    static unsigned kspace[64];
    static unsigned *k;

    static DigestArray h;
    DigestArray abcd;
    DgstFctn fctn;
    short m, o, g;
    unsigned f;
    short *rotn;
    union {
        unsigned w[16];
        char     b[64];
    }mm;
    int os = 0;
    int grp, grps, q, p;
    unsigned char *msg2;

    if (k==NULL) k= calctable(kspace);

    for (q=0; q<4; q++) h[q] = h0[q];   // initialize

    {
        grps  = 1 + (mlen+8)/64;
        msg2 = malloc( 64*grps);
        memcpy( msg2, msg, mlen);
        msg2[mlen] = (unsigned char)0x80;
        q = mlen + 1;
        while (q < 64*grps){ msg2[q] = 0; q++ ; }
        {
            MD5union u;
            u.w = 8*mlen;
            q -= 8;
            memcpy(msg2+q, &u.w, 4 );
        }
    }

    for (grp=0; grp<grps; grp++)
    {
        memcpy( mm.b, msg2+os, 64);
        for(q=0;q<4;q++) abcd[q] = h[q];
        for (p = 0; p<4; p++) {
            fctn = ff[p];
            rotn = rots[p];
            m = M[p]; o= O[p];
            for (q=0; q<16; q++) {
                g = (m*q + o) % 16;
                f = abcd[1] + rol( abcd[0]+ fctn(abcd) + k[q+16*p] + mm.w[g], rotn[q%4]);

                abcd[0] = abcd[3];
                abcd[3] = abcd[2];
                abcd[2] = abcd[1];
                abcd[1] = f;
            }
        }
        for (p=0; p<4; p++)
            h[p] += abcd[p];
        os += 64;
    }
    return h;
}

int main( int argc, char *argv[] )
{
    int j,k;
    char msg[500];
    gets(msg);
    unsigned *d = md5(msg, strlen(msg));
    MD5union u;
    for (j=0;j<4; j++){
        u.w = d[j];
        for (k=0;k<4;k++) 
            printf("%02x",u.b[k]);
    }
    return 0;
}
#包括
#包括
#包括
#包括
联合超宽带{
无符号w;
无符号字符b[4];
}MD5union;
typedef无符号摘要数组[4];
无符号func0(无符号abcd[]{
返回(abcd[1]和abcd[2])|(~abcd[1]和abcd[3]))
无符号func1(无符号abcd[]{
返回(abcd[3]和abcd[1])|(~abcd[3]和abcd[2])}
无符号func2(无符号abcd[]{
返回abcd[1]^abcd[2]^abcd[3];}
无符号func3(无符号abcd[]{
返回abcd[2]^(abcd[1]| ~abcd[3])}
typedef unsigned(*DgstFctn)(unsigned a[]);
无符号*calctable(无符号*k)
{
双s,压水堆;
int i;
压水堆=功率(2,32);

对于C程序中的(i=0;i,假设它是MD5正确地对输入字符串进行散列,那么它实际上可能是正常的

这个问题可能根本不是问题,您的MD5散列可以在两个进程中都是正确的。(尽管它们看起来完全不同,但它们可以“保持”相同的值
'1234'
)只是堆栈在不同的实例之间有不同的内容,null后面的一些字符串来自堆栈

在一个实例中,C函数正在散列这个字符串
'1234\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

另一个实例是散列这个字符串
“1234\u一些随机值”

两个字符串都包含
1234
,后跟
null
字符,但null后面的字符不同

尝试用所有空值预先填充临时字符串,然后在密码中复制,以便在MD5哈希之前确保字符串缓冲区的其余部分为“空”

(如果您想验证我的正确性,可以通过unMD5哈希来确认。从Wikipedia,您可以看到哈希算法接受“块”数据,而不关心空字符的位置:

MD5将可变长度的消息处理为固定长度的输出 128位。输入消息被分成512位的块 (十六个32位字);消息被填充以使其长度为 可被512整除

从这里 同样从这个解释来看,如果密码长度正好是(16个32位字)16=64个字符的4倍,那么MD5哈希应该是相同的,不管空字符后面的字符数组中出现什么,因为算法不会在64个字符边界之后查找更多的字符。 )

尝试添加

memset(msg,0,500); 
在您的
得到
之前


(我忽略了所有的安全问题:)

在您的C程序中,假设它是MD5正确地散列输入字符串,那么它实际上可能是正常的

这个问题可能根本不是问题,您的MD5散列可以在两个进程中都是正确的。(尽管它们看起来完全不同,但它们可以“保持”相同的值
'1234'
)只是堆栈在不同的实例之间有不同的内容,null后面的一些字符串来自堆栈

在一个实例中,C函数正在散列这个字符串
'1234\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

另一个实例是散列这个字符串
“1234\u一些随机值”

两个字符串都包含
1234
,后跟
null
字符,但null后面的字符不同

尝试用所有空值预先填充临时字符串,然后在密码中复制,以便在MD5哈希之前确保字符串缓冲区的其余部分为“空”

(如果您想验证我的正确性,可以通过unMD5哈希来确认。从Wikipedia,您可以看到哈希算法接受“块”数据,而不关心空字符的位置:

MD5将可变长度的消息处理为固定长度的输出 128位。输入消息被分成512位的块 (十六个32位字);消息被填充以使其长度为 可被512整除

从这里 同样从这个解释来看,如果密码长度正好是(16个32位字)16=64个字符的4倍,那么MD5哈希应该是相同的,不管空字符后面的字符数组中出现什么,因为算法不会在64个字符边界之后查找更多的字符。 )

尝试添加

memset(msg,0,500); 
在您的
得到
之前


(我忽略了所有的安全问题:)

我认为这可能是你做两件事的一个好时机

  • 开始考虑设计的安全性
  • 熟悉PHP标准库,尤其是


  • 我首先列出了安全性,因为正如其他人所指出的,你不应该直接访问GET或POST。因为你只是在练习,所以开始编程时,安全性总是在你的mi中