[自己做个游戏服务器三]你帮我为服务器选择一种加密算法,Java实现各种加解密算法

小知识,大挑战!本文正在参与“   程序员必备小知识 

本文同时参与 「掘力星计划」   ,赢取创作大礼包,挑战创作激励金

66.jpeg 毕业好多年了,虽然大学专业学的是信息安全,在大学的时候学过各种加密算法,但是毕业后也没有从事安全行业,一直在做游戏,做web开发,在工作中使用加解密的机会还真不多,但是加解密确实也一直在身边,比如我们游戏通信协议不可避免的对数据进行加密,要不然的话,随便解包有点危险,刷协议骚扰服务器。今天就来聊下常用的加密算法,接下来的服务器也要选择一种加密算法,你帮我选一种?

1、加密算法分类

加密算法大的分类分为可解密算法和不可解密算法

比如 MD5SHAHMAC这三种加密算法,是非可逆加密,就是不可解密的加密方法,我们称之为单向加密算法,常用作验证数据安全。

BASE64 严格地说,属于编码格式,而非加密算法 MD5(Message Digest algorithm 5,信息摘要算法) SHA(Secure Hash Algorithm,安全散列算法)

加密算法一般本分 对称加密和非对称加密

比如 基于“[对称密钥]”的加密算法主要有DES、3DES(TripleDES)、AES、RC2、RC4、RC5和Blowfish

非对称加密:RSA、ECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用)

2、加密算法实现

1. BASE64

Base64用于网络中传输的数据进行编码,严格意义上属于编码的格式,有64个字符的对应的编码,Base64就是将内容按照该格式进行编码。可以对数据编码和解码,是可逆的,安全度较低,不过,也可以作为最基础最简单的加密算法用于加密要求较弱的情况。

Base64可以使用JDk中自带的类实现,还可以使用Bouncy Castle(简称bc)或Commons Codec(简称cc)实现

扫描二维码关注公众号,回复: 13166348 查看本文章

来个例子:

import org.apache.commons.codec.binary.Base64;
​
public class Aain {
    public static byte[] encode2Base64(byte[] bytes) {
        byte[] bts = Base64.encodeBase64(bytes);
        return bts;
    }
    public static byte[] decode2Base64(String str) {
        byte[] bts = Base64.decodeBase64(str);
        return bts;
    }
}
复制代码

2. MD5

MD5(信息-摘要算法5),用于确保信息传输完整一致。,主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。广泛用于加密和解密技术,常用于文件校验。不管文件多大,经过MD5后都能生成唯一的MD5值。

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
​
public class Aain {
    public static String md5(String str) {
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            return new String(digest.digest(str.getBytes()));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
​
    public static void main(String[] args) {
        System.out.println(md5("ddddddddddddd"));;
    }
}
复制代码

linux 下支持md5 命令

计算 文件的md5值
​
md5sum final.nnet 
复制代码

3.SHA

安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。该算法经过加密专家多年来的发展和改进已日益完善,并被广泛使用。该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。散列函数值可以说是对明文的一种"指纹"或是"摘要"所以对散列值的数字签名就可以视为对此明文的数字签名。

import java.math.BigInteger;
import java.security.MessageDigest;
​
public class Aain {
    public static final String  KEY_SHA = "SHA";
​
​
    public static void sha(String inputStr) {
        byte[] inputData = inputStr.getBytes();
        try {
            MessageDigest messageDigest = MessageDigest.getInstance(KEY_SHA);
            messageDigest.update(inputData);
            BigInteger sha = new BigInteger(messageDigest.digest());
            System.out.println("SHA加密后:" + sha.toString(32));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
​
​
    public static void main(String[] args) {
        sha("ddddddddddddd");
    }
}
复制代码

4.AES

AES加密是对称加密 128 192 256 分别表示密钥的长度

AES的加密方式会将明文拆分成不同的块进行加密

AES现在广泛用于金融财务、在线交易、无线通信、数字存储等领域,经受了最严格的考验,但说不定哪天就会步DES的后尘。

package com.xin;
​
import org.springframework.util.Base64Utils;
​
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
​
public class Aain {
​
    private static final String KEY_ALGORITHM = "AES";
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";//默认的加密算法
​
    /**
     * AES 加密操作
     *
     * @param content 待加密内容
     * @param key     加密密钥
     * @return 返回Base64转码后的加密数据
     */
    public static String encrypt(String content, String key) {
        try {
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器
​
            byte[] byteContent = content.getBytes();
​
            cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));// 初始化为加密模式的密码器
​
            byte[] result = cipher.doFinal(byteContent);// 加密
​
            return Base64Utils.encodeToString(result);//通过Base64转码返回
​
        } catch (Exception ex) {
        }
​
        return null;
    }
​
    /**
     * AES 解密操作
     *
     * @param content
     * @param key
     * @return
     */
    public static String decrypt(String content, String key) {
​
        try {
            //实例化
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
​
            //使用密钥初始化,设置为解密模式
            cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));
​
            //执行操作
            byte[] result = cipher.doFinal(Base64Utils.decodeFromString(content));
​
            return new String(result);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
​
        return null;
    }
​
    /**
     * 生成加密秘钥
     *
     * @return
     */
    private static SecretKeySpec getSecretKey(final String key) {
        //返回生成指定算法密钥生成器的 KeyGenerator 对象
        KeyGenerator kg = null;
​
        try {
            kg = KeyGenerator.getInstance(KEY_ALGORITHM);
​
            //AES 要求密钥长度为 128
            kg.init(128, new SecureRandom(key.getBytes()));
​
            //生成一个密钥
            SecretKey secretKey = kg.generateKey();
​
            return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为AES专用密钥
        } catch (NoSuchAlgorithmException ex) {
        }
​
        return null;
    }
​
    public static void main(String[] args) {
        String content = "大家好,我是香菜,公众号:香菜聊游戏";
        String key = "sde@5f98H*^hsff%dfs$r344&df8543*er";
        System.out.println("content:" + content);
        String s1 = Aain.encrypt(content, key);
        System.out.println("加密后内容 :" + s1);
        System.out.println("解密后内容:" + Aain.decrypt(s1, key));
​
    }
​
}
​
复制代码

3、总结

加密算法是游戏协议必须要用的,但是也不复杂,一次性工作,网上也有大片的解决方案,但是自己写一下还是必要的,事情只有在下手的那一刻才会遇到困难。

还有就是不试试你怎么好让自己放弃。哈哈,不扯了,加油吧

猜你喜欢

转载自juejin.im/post/7017729810864537637