⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sauthen.c

📁 采用非对称密钥加密方式的应用系统认证系统
💻 C
字号:
#include "windows.h"
#include "winbase.h"

#include "sauthen.h"


/*将十进制转化为十六进制*/
int  IntToHex(char *bufback, int iValue);
/*将十六进制转化为十进制, len为十六进制数的长度,返回转化后的十进制值*/
int  HexToInt(char *h, int n);
/*显示信息ShowMessage,perror,printf()*/
/*void  CommonShow(char*);*/
void  CommonShow(char *Text, char*MessageBuf);
/*从套接字读入n个字节,返回已读到的字节数,为0:已到文件尾或socket已断开,小于0:发生错误*/
int Readn(SOCKET Fd,char *Buf,int n);
int CloseSocket(SOCKET ConnFd);

int ReadRemotePakeage(SOCKET ConnFd, char *BufBack);
int SendRemotePakeage(SOCKET ConnFd, char *Buf, int iLen);
int BuildPackage(char *BufBack, char *MsgBodyText, int MsgBodyLen, int FieldsCount, char *MsgType, char *ReturnCode);


extern int SecureAuthen(char *cOperator, char *Password, char *GsmUsername, char *GsmPassword, char *CdrUsername, char *CdrPassword, char *AppName, char *Message, char *Key)
{
  SOCKET SockFd;
  struct sockaddr_in servaddr;
  char   ServerAddress[16];
  char   LocalAddress[16];
  char   LocalHostName[100];
  char   ProcessId[11];
  struct hostent *LocalHostInfo;

  char MsgBodyText[MAX_BUFFER_SIZE]; /*需要发送的未加密包体*/
  int  MsgBodyTextLen;
  char Buf[MAX_BUFFER_SIZE];
  char BufBack[MAX_BUFFER_SIZE];
  int MsgLen;
  char MsgType[3];
  char RecvText[MAX_BUFFER_SIZE];
  char SendText[MAX_BUFFER_SIZE];
  int  RecvTextLen;
  char *pCur;
  int iStatus;
  int iLen;
  int BodyLen;
  R_RSA_PUBLIC_KEY  ServerPublicKey;
  int ServerPublicKeyReady=0;
  R_RSA_PUBLIC_KEY  ClientPublicKey ;
  R_RSA_PRIVATE_KEY ClientPrivateKey;
  R_RANDOM_STRUCT randomStruct;
  R_RSA_PROTO_KEY protoKey;
  WSADATA ws;
  u_short *p; int i;
  static int ClientKeyReady=0;

  sprintf(ProcessId, "%10d", GetCurrentProcessId());

  R_RandomCreate(&randomStruct);
  protoKey.bits=KEY_BITS;
  protoKey.useFermat4 = 1;
  if (strcmp(Key, "license.authen.com.cn")!=0) {CommonShow("Warning...NO LICENSE!!", Message);return(-100);}

  if (ClientKeyReady==0 && R_GeneratePEMKeys(&ClientPublicKey, &ClientPrivateKey, &protoKey, &randomStruct)!=0) {
      CommonShow("生成钥匙对出错! SecureAuthen", Message);
      ClientKeyReady=0;
      return(-1);
  }
  else ClientKeyReady=1;
  WSAStartup(0x0101, &ws);
  memset(LocalAddress, 0, 16);
  if (gethostname(LocalHostName, sizeof(LocalHostName))==0)
      if ((LocalHostInfo=gethostbyname(LocalHostName))!=NULL)
          strcpy(LocalAddress, inet_ntoa(* (struct in_addr*)*LocalHostInfo->h_addr_list ));

  if ((SockFd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
      CommonShow("socket创建出错!SecureAuthen", Message);
      closesocket(SockFd);
      return(-2);
  }
  strcpy(ServerAddress, "130.34.2.15");
  servaddr.sin_family=AF_INET;
  servaddr.sin_port=htons(LISTEN_PORT);
  servaddr.sin_addr.s_addr=inet_addr(ServerAddress);

  bind(SockFd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr));

  if ((iStatus=connect(SockFd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr))) < 0) {
      closesocket(SockFd);
      if ((SockFd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
          CommonShow("socket创建出错!SecureAuthen", Message);
          closesocket(SockFd);
          return(-2);
          }
      strcpy(ServerAddress, "130.34.2.17");
      servaddr.sin_family=AF_INET;
      servaddr.sin_port=htons(LISTEN_PORT);
      servaddr.sin_addr.s_addr=inet_addr(ServerAddress);
      bind(SockFd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr));
      if (connect(SockFd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr)) < 0) {
          CommonShow("连接服务器出错!SecureAuthen", Message);
          closesocket(SockFd);
          return(-3);
          }
      }
  sprintf(MsgBodyText, "%4X", sizeof(ClientPublicKey));
  memcpy(MsgBodyText+4, &ClientPublicKey, sizeof(ClientPublicKey));
  BodyLen=sizeof(ClientPublicKey)+4;
  p=(unsigned short*)(MsgBodyText+4); for(i=0;i<sizeof(ClientPublicKey);i=i+2) *p=ntohs(*p);
  MsgLen=BuildPackage(Buf, MsgBodyText, BodyLen, 1, "EX", "0000");
  if (SendRemotePakeage(SockFd, Buf, MsgLen)<0) {
      CommonShow("发送数据包出错!SecureAuthen", Message);
      closesocket(SockFd);
      return(-4);
  }
  while(1) {
      memset(BufBack, 0, MAX_BUFFER_SIZE);
      if ((MsgLen=ReadRemotePakeage(SockFd, BufBack))<0) {
          closesocket(SockFd);
          CommonShow("接收数据包出错!", Message);
          return(-5);
      }
      strncpy(MsgType, BufBack+4, 2); MsgType[2]=0;
      if (strcmp(MsgType, "EX")==0) {
          iLen=HexToInt(BufBack+12, 4);
          if (iLen!=sizeof(ServerPublicKey)) {
              CommonShow("公钥交换发生异常!", Message);
              return(-6);
          }
          else {
              p=(unsigned short*)(BufBack+12+4); for(i=0;i<sizeof(ClientPublicKey);i=i+2) *p=htons(*p);
              memcpy(&ServerPublicKey, (BufBack+12+4), sizeof(ServerPublicKey));
              ServerPublicKeyReady=1;

              memset(SendText, 0, MAX_BUFFER_SIZE);
              pCur=SendText;
              iLen=strlen(cOperator);
              sprintf(pCur, "%4X", iLen);
              memcpy(pCur+4, cOperator, iLen); pCur=pCur+4+iLen;
              iLen=strlen(Password);
              sprintf(pCur, "%4X", iLen);
              memcpy(pCur+4, Password, iLen); pCur=pCur+4+iLen;
              iLen=strlen(LocalAddress);
              sprintf(pCur, "%4X", iLen);
              memcpy(pCur+4, LocalAddress, iLen); pCur=pCur+4+iLen;
              *pCur=0;

              iLen=pCur-SendText;
              iStatus=RSAPublicEncrypt(MsgBodyText, &MsgBodyTextLen, SendText, iLen, &ServerPublicKey, &randomStruct);
              MsgLen=BuildPackage(Buf, MsgBodyText, MsgBodyTextLen, 5, "RQ", "0000");
              SendRemotePakeage(SockFd, Buf, MsgLen);
          }

      }
      else {
          if (strcmp(MsgType, "RP")==0) {     /********登录返回包********/
              if (ServerPublicKeyReady==0) {
                  closesocket(SockFd);
                  CommonShow("未收到公钥交换包!", Message);
                  return(-6);
                }
              else {
                  memset(RecvText, 0, MAX_BUFFER_SIZE);
                  iStatus=RSAPrivateDecrypt(RecvText, &RecvTextLen, BufBack+12, MsgLen-12, &ClientPrivateKey);
                  if (iStatus!=0) {
                      closesocket(SockFd);
                      CommonShow("解密数据包出错!", Message);
                      return(-7);
                  }
                  pCur=RecvText;
                  if ((iLen=HexToInt(pCur, 4))<0) goto HexToIntError;
                  memcpy(GsmUsername,pCur+4,iLen);GsmUsername[iLen]=0;pCur=pCur+4+iLen;
                  if ((iLen=HexToInt(pCur, 4))<0) goto HexToIntError;
                  memcpy(GsmPassword,pCur+4,iLen);GsmPassword[iLen]=0;pCur=pCur+4+iLen;
                  if ((iLen=HexToInt(pCur, 4))<0) goto HexToIntError;
                  memcpy(CdrUsername,pCur+4,iLen);CdrUsername[iLen]=0;pCur=pCur+4+iLen;
                  if ((iLen=HexToInt(pCur, 4))<0) goto HexToIntError;
                  memcpy(CdrPassword,pCur+4,iLen);CdrPassword[iLen]=0;pCur=pCur+4+iLen;

                  closesocket(SockFd);
                  return(0);
              }
          }
          else {       /********消息类型包********/
              if (strcmp(MsgType, "MG")!=0) {
                  strcpy(Message, "无法识别数据包类型!");
              }
              else {
                  pCur=BufBack;
                  if ((iLen=HexToInt(pCur, 4))<0) goto HexToIntError;
                  memcpy(Message,pCur+12+4,iLen);Message[iLen]=0;pCur=pCur+12+4+iLen;
              }
              return(1);
          }
      HexToIntError:
          closesocket(SockFd);
          CommonShow("十六进制转化出错!", Message);
          return(-7);
      }
  } /*end of while(1)*/

}



/************************************************************
 *ReturnValue: 数据包字节数                                 *
 ************************************************************/
int ReadRemotePakeage(SOCKET ConnFd, char *BufBack)
{
  int MsgLen;
  int n;
  fd_set ConnSet;
  struct timeval tvConnTimeOut;

  FD_ZERO(&ConnSet);
  FD_SET(ConnFd, &ConnSet);
  tvConnTimeOut.tv_sec=TIME_OUT;

  if ((n=select(ConnFd+1,&ConnSet,NULL,NULL,&tvConnTimeOut))<=0) {
      CommonShow("select出错!ReadRemotePakeage", NULL);
      return(-1);
  }

  /*调用Readn函数从缓冲区中读入数据到buf*/
  if ((n=Readn(ConnFd, BufBack, MSGLEN_BYTES))<0) {
      CommonShow("ReadRemotePackage error when read lenth", NULL);
      return(-2);
  }
  else if(n==0) return(-3);

  if ((MsgLen=HexToInt(BufBack,MSGLEN_BYTES))<0) {
      CommonShow("Received a non hex string, ReadRemotePackage", NULL);
      return(-4);
      }

  if ((n=Readn(ConnFd,BufBack+MSGLEN_BYTES,MsgLen-MSGLEN_BYTES))<0) {
      CommonShow("ReadRemotePackage error when read lenth", NULL);
      return(-5);
  }
  else if (n==0) return(-6);
  return(n+MSGLEN_BYTES);
}
/************************************************************/
int SendRemotePakeage(SOCKET ConnFd, char *Buf, int iLen)
{
  int n;
  fd_set ConnSet;
  struct timeval tvConnTimeOut;

  FD_ZERO(&ConnSet);
  FD_SET(ConnFd, &ConnSet);
  tvConnTimeOut.tv_sec=TIME_OUT;

  if ((n=select(ConnFd+1,NULL,&ConnSet,NULL,&tvConnTimeOut))<=0) {
      CommonShow("select出错!SendRemotePakeage", NULL);
      return(-1);
  }
  /**/
  if ((n=send(ConnFd, Buf, iLen, NULL))!=iLen) {
      CommonShow("SendRemotePackage error", NULL);
      return(-2);
      }
  return n;
}
/************************************************************/
/*验证处理函数
 *ReturnValue: 返回包的字节数                               *
/************************************************************/
int BuildPackage(char *BufBack, char *MsgBodyText, int MsgBodyLen, int FieldsCount, char *MsgType, char *ReturnCode)
{
  char Msg[40];
  if (MsgBodyLen >= (MAX_BUFFER_SIZE-12) || MsgBodyLen < 0) {
      strcpy (Msg, "数据包溢出!");
      sprintf(MsgBodyText, "%4X", strlen(Msg));
      strcpy (MsgBodyText+4, Msg);  
      strcpy (MsgType, "MG");
      MsgBodyLen=4+strlen(Msg);
      FieldsCount=1;
      strcpy(ReturnCode, "0004");
  }
  sprintf(BufBack, "%4X", MsgBodyLen+12);
  memcpy (BufBack+4, MsgType, 2);
  sprintf(BufBack+6, "%2X", FieldsCount);
  memcpy (BufBack+8, ReturnCode, 4);
  memcpy (BufBack+12,MsgBodyText,MsgBodyLen);
  return(MsgBodyLen+12);
}
/************************************************************/ 
int Readn(SOCKET Fd,char *Buf,int n)
{
  int m;
  int ReadNum;
  char *p;
  int iErrno;
  p=Buf;
  m=n;
ReadnAgain:
	if((ReadNum=recv(Fd,p,m,NULL))<0)
	{
	    iErrno=WSAGetLastError();    
	    if (iErrno==WSAEINTR)
                goto ReadnAgain;
            else if (iErrno==WSAECONNRESET)
                 return(0);
            return(-abs(iErrno));
	}
	else if (ReadNum==0)
                return(0);
             else {
                p+=ReadNum;
                m-=ReadNum;
		if(m==0)
		{
		    *p=0;
		    return(n);
		}
		else if(m>0) {
                         goto ReadnAgain;
                     }
                     else {
                         *p=0;
                         return(-10000);
                          }
                }
}
/************************************************************/
void  CommonShow(char *Text, char*MessageBuf)
{
  printf("%s", Text);
  if (MessageBuf) strcpy(MessageBuf, Text);
}
int  IntToHex(char *bufback, int iValue)
{
  sprintf(bufback, "%4X", iValue);
  return(0);
}
int CloseSocket(SOCKET ConnFd)
{
  closesocket(ConnFd);
  WSACleanup();
}
int  HexToInt(char *h, int n)
{
	int s;
	int i;
	int a[10];
	if(n==0) n=strlen(h);
    for(i=0;i<n;i++)
        if((h[i]>='0')&&(h[i]<='9'))
            a[i]=h[i]-48;
        else if((h[i]>='A')&&(h[i]<='F'))
            a[i]=h[i]-55;
        else if((h[i]>='a')&&(h[i]<='f'))
            a[i]=h[i]-87;
        else if (h[i]==' ')
            a[i]=0;
        else
        {
            CommonShow("Error,The string is not a hex string:HexToDeci", NULL);
            return(-10000);
        }
   	s=a[0];
	for(i=1;i<n;i++)
		s=s*16+a[i];
	return(s);
}
/************************************************************/

/*
main()
{
  char cOperator[100];
  char Password[100];
  char Depart[8];
  char Areacode[2];
  char GsmUsername[11];
  char GsmPassword[21];
  char CdrUsername[11];
  char CdrPassword[21];
  char AppName[21];
  char Message[101];
  char Key[21];
  int  iReturn;
  int i;

  strcpy(cOperator,"A00SYS");
  strcpy(Password,"gsm321");
  for(i=0;i<200;i++)
     if (iReturn=SecureAuthen(cOperator, Password, GsmUsername, GsmPassword,
                       CdrUsername, CdrPassword, "Login.exe", Message, "license.authen.com.cn"))
         {printf("i:%d",i);CommonShow("Error",NULL);break;}
  Message[100]=0;

  if (iReturn==0) {
      CommonShow(GsmPassword, NULL);
      }
  else CommonShow(Message, NULL);

} */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -