cocos-lua des加密c++ java

0x000 背景

第一次写博文,而且还憋坏了,就啰嗦点吐槽一下这苦逼的两天。没有大佬带真难。
(成品在最后,前面只是我踩坑的辛酸历程,工科生文笔不好,不喜欢看的可以直接往后面拉)
运营中项目出了外挂,无奈跑来研究两天DES加密。我们服务器是java写的,前端cocos需要支持跨平台,用c++写是最合适的。然后我就开启了苦逼的两天。
我不是科班出身,由于工作写了几年lua,c++只是半生不熟的小白一个,基本处于勉强能看懂简单语意的地步,而java我也只是为了android打包和接第三方sdk了解过皮毛(此处应该是只了解过毛尖尖,还没完全了解够一根毛)。

0x010 Day1

新冠搞得我在家办公闲的蛋疼,所以一起床就干劲十足,上网一搜,70年代最基础加密方式?那搁现在不是小菜一碟!然鹅,啥?啥?数据分成两份,左换右,右换左再继续换,换得头都大了,我直接给同事说:“我放弃自己写一份了,我去网上搜一份好了。”同事回答:“好的,我写好了。”什么鬼?这么快的嘛?找到现成的了?同事:“java有自己的javax.crypto.Cipher,里面就有DES加密。”好的吧,有现成的你6p,我也去网上捞一份去。
捞了第一份(最后没有采用,这里就不链接出来了),啥玩意?到处报错,md5?咋这算法原理没提到需要md5验证的啊?这里咋还用了md5?删掉删掉。怎么还在报错?嗯?这个转换成字符串函数是什么鬼?我怎么找不到?是不是我拷贝掉了?一翻原帖:“此处base64编码请读者自己按需要写一份。”我xxxxxx。。。。
我:“我看网上很多说加密出来的数据需要用base64处理一次?”
同事:“那我base64编码一次处理给你。”
我:“。。。。把你base64解码文件发我,我直接翻成c++好了,懒得写了。”(后面那段关于base64编码的是我自己翻的,中途还各种问函数在干啥,写得难免很渣,有自用的可以自己替换。)
时间又过去了一小时,我:“终于弄好了,等等,他这写的类方法,该怎么调用?”
(当时是真的忘了c++怎么写,这块又跑去百度了几分钟才搞定)
我:“来来来!走起走起,来个密钥密文我跑一下。”
同事:“好的,给你。”
过了半小时。同事:“怎么样了?”我:“你这不对吧,我怎么解都是乱码。把你明文给我,我看看差距多大。”“好的,给你。”“???你这怎么有中文啊?一上来就给我地狱模式?我新手!”“好嘛,那我给你纯英文的,你再试试这个”又过了半小时。同事:“怎么样?”“。。。”我:“还是乱码。我搜到篇帖子,说java自带的Cipher和c++使用的openssl不匹配。但是我这也没有使用openssl啊,你那边看得到源码不?我看看跟我这边又哪些地方对不上。”同事:“他这个包里看不到的。”“我这个自带了个加密,我试了下,我这边加密的能解出来,而且我这边加密出来的数据跟你那个差距很大。”同事:“那怎么办?”我:“你那边看不见源码,要不你拿我这分去翻译成java好了。”同事:“。。。好,我试试。”
三个小时过去了,中途各种问是声明的什么类型,函数是在做什么操作。同事:“我放弃了,这翻不出来。”我:“你要不看看这篇帖子?这篇帖子说解决了java和c++直接通信对不上的问题。”同事:“好,我去看看。”“那我也拷那份来用。”过了几分钟。同事:“你试试这个密钥和密文能不能解。”我:“???你这么快的嘛?”同事:“拷过来就能用。”我:“。。。我不得行,那你再等我会。”
又两个小时过去。我:“我xxxxx,Xcode这是有病吧?这函数声明在这.h,实现在这.c,他怎么就一直找不到?”同事:“。。。”“算了,12点了,我放弃了,明早我还要早起更新,明天再来吧。”
始终编译不过

0x020 Day2

0x021柳暗

第二天,我还是无法处理好Xcode找不到函数的问题。被迫无奈去翻帖子,找到了这篇帖子
我:“你要不试试这个?”
“好。”
同事:“我这边好了,你试试这个密钥和密文。”
“又这么快?我这边又出昨天那问题了。”
“不是拷过来就能用嘛?”
“不是。。。我想到一种处理方式了,我按第一次我们尝试的那种类的方式去写,那种不会报这个错误,虽然不知道原理是啥。”
“好。”
过了半小时。我:“怎么还是乱码?”同事:“还是不得行啊,怎么办?”“等等,你这有点问题,他这里解密都是按8位取的,怎么你给我的有33位?这样的话后面7位就取不到了。我找到原因了,你坑我,你给我多复制了一个[!”同事:“。。。。”
改成类方法的解密

0x022花明

我:“怎么还是对不上。”同事:“还是不行嘛?”
“我拿你给我的明文自己加密了之后,跟你加密的前半段能对上,后半段是什么鬼?我这边压根就没有,你明文后面那两个无法识别的字符是什么鬼?”
“我也不知道,这应该是他自动填充的。而且他这注释说的是翻译的c的方法,我也看不懂啥意思。”
我:“我凑,我知道了,这尼玛他是取的后8位按16进制展示出来的,所以你给我这一段我压根没法解密回去。”(其实我也没细看,我只看了这块操作与运算取低8位,感觉会舍了高8位应该没法还原)
“那怎么办?”
“这样,你别用他那个byteHEX,这应该是他拿来打印的,你把数据走base64编码后给我。就用我翻译的你的base64那个,别搞得对不上了。”
“好,我试试。”
“这个你试下呢。”
“好,马上,我在开启。”
“奈斯!终于解出来了。”
最后测试终于解出来了

0x023又一村

同事:“终于过了。”
我:“嗯,你去弄接口,我还要弄成工具方法注册到lua给lua调用”
一小时后。
以下全是我自言自语。
“我特么,这什么鬼?#include 都能给我报错?什么垃圾Xcode噢?”
“尼玛string能找到了这其他的文件又怎么报错了?还能不能好好玩了?”
“算了算了,苹果你是大爷,我不用std::string了好吧。”
“??怎么又找不到了,什么鬼哟!”

过去了一个多小时,终于磕磕绊绊的把方法注册到了lua端。现在,就等着调试接口了。
祝我好运。

正式运营的项目,项目相关的被我删除了,工程请自建。如若转载,代码请勿收费,利人利己,谢谢合作
des.h:

#ifndef _DES_H_
#define _DES_H_

#include <lua.h>

//这里原本有个u_char的定义,在打包android时与系统中的u_char定义重复引起报错,所以被我删除了
//所有u_char手动改为了unsigned char
#define _u8 unsigned char
#define _u16 unsigned short
#define _u32 unsigned int

#ifdef WIN32
extern "C" {
   
#endif

    int luaopen_des(lua_State *L); //这里是注册到lua的接口
#ifdef WIN32
}
#endif
#endif

des.c:

#include "des.h"

#include <lauxlib.h>
#include <string.h>

//这几个函数声明原本是放在.h文件的,不知道为什么我xcode会一直报错找不到函数实现,所以挪过来了
//有知道的大佬麻烦留言解答让我学习一下,感激不尽
void FDES(unsigned char *key,unsigned char *text,unsigned char *mtext);
void _FDES(unsigned char *key,unsigned char *mtext,unsigned char *text);
void Fencrypt0(unsigned char *text,unsigned char *mtext);
void Fdiscrypt0(unsigned char *mtext,unsigned char *text);
void Fexpand0(unsigned char *in,unsigned char *out);
void Fcompress0(unsigned char *out,unsigned char *in);
void Fcompress016(unsigned char *out,unsigned char *in);
void Fsetkeystar(unsigned char bits[64]);
void FLS(unsigned char *bits,unsigned char *buffer,int count);
void Fson(unsigned char *cc,unsigned char *dd,unsigned char *kk);
void Fiip(unsigned char *text,unsigned char *ll,unsigned char *rr);
void _Fiip(unsigned char *text,unsigned char *ll,unsigned char *rr);
void FF(int n,unsigned char *ll,unsigned char *rr,unsigned char *LL,unsigned char *RR);
void Fs_box(unsigned char *aa,unsigned char *bb);

unsigned char C[17][28],D[17][28],K[17][48];

//这块是翻译的同事给我的Java的Base64方法,原本是分了一个文件,但是xcode死活找不到,就也挪过来了
static const char * legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

//
static int decode64(char c)
{
   
    if (c >= 'A' && c <= 'Z')
        return ((int) c) - 65;
    else if (c >= 'a' && c <= 'z')
        return ((int) c) - 97 + 26;
    else if (c >= '0' && c <= '9')
        return ((int) c) - 48 + 26 + 26;
    else
        switch (c) {
   
            case '+':
                return 62;
            case '/':
                return 63;
            case '=':
                return 0;
        }
    return 0;
}

static int deBase64(char * s, int len, char * os)
{
   
    int i = 0;
    int idx = 0;
    
    while (1)
    {
   
        while (i < len && s[i] <= ' ')
            i++;
        
        if (i == len)
            break;
        
        int tri = (decode64(s[i]) << 18)
        + (decode64(s[i + 1]) << 12)
        + (decode64(s[i + 2]) << 6)
        + (decode64(s[i + 3]));
        
        os[idx] = ((tri >> 16) & 255);
        idx += 1;
        if (s[i + 2] == '=')
            break;
        os[idx] = ((tri >> 8) & 255);
        idx += 1;
        if (s[i + 3] == '=')
            break;
        os[idx] = (tri & 255);
        idx += 1;
        
        i += 4;
    }
    return idx;
}

//由于std::string无法使用,这里传一个buffer把数据带出去
static int enBase64(char * data, int len, char * buf)
{
   
    int start = 0;
    int idx = 0;
    
    int end = len - 3;
    int i = start;
    int n = 0;
    
    while (i <= end) {
   
        int d = ((((int) data[i]) & 0x0ff) << 16)
        | ((((int) data[i + 1]) & 0x0ff) << 8)
        | (((int) data[i + 2]) & 0x0ff);
        
        buf[idx] = (legalChars[(d >> 18) & 63]);
        buf[idx + 1] = (legalChars[(d >> 12) & 63]);
        buf[idx + 2] = (legalChars[(d >> 6) & 63]);
        buf[idx + 3] = (legalChars[d & 63]);
        idx += 4
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值