Java常用加解密算法

1均芽、BASE64

BASE64嚴(yán)格地說,應(yīng)該說是屬于編碼格式单鹿,而非加密算法掀宋。

加解密:

    /**
     * 加密
     */
    public static String encryptBASE64(byte[] data) {
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);
    }


    /**
     * 解密
     */
    public static byte[] decryptBASE64(String cipher) {
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] bytes = null;
        try {
            bytes = decoder.decodeBuffer(cipher);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bytes;
    }

2、MD5和SHA

MD5(Message Digest algorithm 5仲锄,信息摘要算法)劲妙,常用于文件校驗。
SHA(Secure Hash Algorithm儒喊,安全散列算法)镣奋,同樣屬于非可逆的算法,作用與MD5相類似怀愧。
MD5輸出是128位的侨颈,SHA輸出是160位的。SHA相較于MD5而言更加安全芯义,當(dāng)然加密花費時間也更長一點哈垢。

先設(shè)置常量

private final static String KEY_SHA = "SHA";
private final static String KEY_MD5 = "MD5";

加密

    /**
     * MD5加密
     */
    public static String encryptMD5(byte[] data) {
        String cipher = null;
        try {
            MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
            md5.update(data);
            cipher = encryptBASE64(md5.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return cipher;
    }

    /**
     * SHA加密
     */
    public static String encryptSHA(byte[] data) {
        String cipher = null;
        try {
            MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
            sha.update(data);
            cipher = encryptBASE64(sha.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return cipher;
    }

3、RSA

RSA算法是一種非對稱密碼算法扛拨。詳情見RSA算法
)

設(shè)置需要用到常量,RSA_INIT_LENGTH為密鑰的初始化長度耘分,密鑰的長度越長,安全性就越好,但是加密解密所用的時間就會越多求泰。一次能加密的密文長度為:密鑰的長度/8-11央渣。所以1024bit長度的密鑰一次可以加密的密文為1024/8-11=117bit。所以非對稱加密一般都用于加密對稱加密算法的密鑰渴频,而不是直接加密內(nèi)容芽丹。對于小文件可以使用RSA加密,但加密過程仍可能會使用分段加密枉氮。

private final static String KEY_RSA = "RSA";
private final static int RSA_INIT_LENGTH = 1024;

3.1志衍、java中初始化生成公鑰和私鑰

    /**
     * 初始化
     */
    public static String[] initRSAKey() {
        String[] keys = null;
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_RSA);
            keyPairGenerator.initialize(RSA_INIT_LENGTH);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            // 公鑰
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            // 私鑰
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            keys = new String[]{encryptBASE64(publicKey.getEncoded()), encryptBASE64(privateKey.getEncoded())};
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return keys;
    }

3.2、加解密

RSA有兩個密鑰聊替,所以加解密方式也有兩種楼肪,一種是“私鑰加密-公鑰解密”,另一種就是“公鑰加密-私鑰解密”惹悄,加解密的實現(xiàn)如下:

    /**
     * 私鑰加密
     */
    public static byte[] encryptByPrivateKey(byte[] data, String key) {
        try {
            byte[] keyBytes = decryptBASE64(key);
            // 獲得私鑰
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA);
            Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            // 對數(shù)據(jù)加密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 公鑰解密
     */
    public static byte[] decryptByPublicKey(byte[] data, String key) {
        try {
            // 對私鑰解密
            byte[] keyBytes = decryptBASE64(key);
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA);
            Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            // 對數(shù)據(jù)解密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, publicKey);

            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 公鑰加密
     */
    public static byte[] encryptByPublicKey(byte[] data, String key) {
        try {
            // 對公鑰解密
            byte[] keyBytes = decryptBASE64(key);
            // 取公鑰
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA);
            Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            // 對數(shù)據(jù)解密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);

            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 私鑰解密
     */
    public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
        try {
            // 對私鑰解密
            byte[] keyBytes = decryptBASE64(key);
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA);
            Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            // 對數(shù)據(jù)解密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, privateKey);

            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

3.3 簽名驗證

使用RSA進行簽名驗證春叫。數(shù)字簽名技術(shù)是將摘要信息用發(fā)送者的私鑰加密,與原文一起傳送給接收者泣港。接收者只有用發(fā)送者的公鑰才能解密被加密的摘要信息暂殖,然后用對收到的原文產(chǎn)生一個摘要信息,與解密的摘要信息對比当纱。如果相同呛每,則說明收到的信息是完整的,在傳輸過程中沒有被修改坡氯,否則說明信息被修改過晨横,因此數(shù)字簽名能夠驗證信息的完整性。

該方法可行有兩個的條件:

1箫柳、通過公鑰推算出私鑰的做法不可能實現(xiàn)
2手形、即使傳輸數(shù)據(jù)的過程被攔截,因為攔截者沒有私鑰悯恍,改動數(shù)據(jù)就會導(dǎo)致簽名的不一致库糠。(這里需要注意,攔截者還是可以使用公鑰對數(shù)據(jù)進行解密涮毫,看到傳輸?shù)臄?shù)據(jù)的)

定義常量

private final static String RSA_MD5 = "MD5withRSA";

簽名和簽名驗證

    /**
     * 私鑰簽名
     */
    public static String signByPrivateKey(byte[] data, String privateKey) {
        try {
            // 解密私鑰
            byte[] keyBytes = decryptBASE64(privateKey);
            // 構(gòu)造PKCS8EncodedKeySpec對象
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
            // 指定加密算法
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA);
            // 取私鑰匙對象
            PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            // 用私鑰對信息生成數(shù)字簽名
            Signature signature = Signature.getInstance(RSA_MD5);
            signature.initSign(privateKey2);
            signature.update(data);
            return encryptBASE64(signature.sign());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 公鑰驗證
     */
    public static boolean verifyByPublicKey(byte[] data, String publicKey, String sign) {
        try {
            // 解密公鑰
            byte[] keyBytes = decryptBASE64(publicKey);
            // 構(gòu)造X509EncodedKeySpec對象
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
            // 指定加密算法
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA);
            // 取公鑰匙對象
            PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec);
            Signature signature = Signature.getInstance(RSA_MD5);
            signature.initVerify(publicKey2);
            signature.update(data);
            // 驗證簽名是否正常
            return signature.verify(decryptBASE64(sign));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

4瞬欧、DES

DES(全稱為DataEncryption Standard,即數(shù)據(jù)加密標(biāo)準(zhǔn))罢防,是一種對稱加密算法黍判!

定義常量

private final static String KEY_DES = "DES";

加解密,其中key是8位的密碼

    /**
     * 加密
     */
    public static byte[] encryptDES(byte[] data, String key) {
        try {
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(key.getBytes());
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_DES);
            SecretKey secureKey = keyFactory.generateSecret(desKey);
            Cipher cipher = Cipher.getInstance(KEY_DES);
            cipher.init(Cipher.ENCRYPT_MODE, secureKey, random);
            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解密
     */
    public static byte[] decryptDES(byte[] data, String key) {
        try {
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(key.getBytes());
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_DES);
            SecretKey secureKey = keyFactory.generateSecret(desKey);
            Cipher cipher = Cipher.getInstance(KEY_DES);
            cipher.init(Cipher.DECRYPT_MODE, secureKey, random);
            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末篙梢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子美旧,更是在濱河造成了極大的恐慌渤滞,老刑警劉巖贬墩,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異妄呕,居然都是意外死亡陶舞,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門绪励,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肿孵,“玉大人,你說我怎么就攤上這事疏魏⊥W觯” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵大莫,是天一觀的道長蛉腌。 經(jīng)常有香客問我,道長只厘,這世上最難降的妖魔是什么烙丛? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮羔味,結(jié)果婚禮上河咽,老公的妹妹穿的比我還像新娘。我一直安慰自己赋元,他們只是感情好忘蟹,可當(dāng)我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著们陆,像睡著了一般寒瓦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上坪仇,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天杂腰,我揣著相機與錄音,去河邊找鬼椅文。 笑死喂很,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的皆刺。 我是一名探鬼主播少辣,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼羡蛾!你這毒婦竟也來了漓帅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎忙干,沒想到半個月后器予,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡捐迫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年乾翔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片施戴。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡反浓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赞哗,到底是詐尸還是另有隱情雷则,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布懈玻,位于F島的核電站巧婶,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏涂乌。R本人自食惡果不足惜艺栈,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望湾盒。 院中可真熱鬧湿右,春花似錦、人聲如沸罚勾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽尖殃。三九已至丈莺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間送丰,已是汗流浹背缔俄。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留器躏,地道東北人俐载。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像登失,于是被迫代替她去往敵國和親遏佣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容