Apache James數(shù)據(jù)庫存儲用戶信息的密碼加密問題及解決方案
項目場景
Apache James郵件服務(wù)器使用數(shù)據(jù)庫來存儲用戶信息的密碼加密問題:
- 將James的用戶改為數(shù)據(jù)庫存儲
- James密碼是如何加密驗證的
1.將James的用戶改為數(shù)據(jù)庫存儲
1、修改存儲方式
找到j(luò)ames-2.3.2\apps\james\SAR-INF\config.xml
找到<users-store>標簽,注釋掉原來文件存儲的方式,改為數(shù)據(jù)庫的方式
maildb:是后面配置的數(shù)據(jù)源名稱
mail_users:是存儲用戶信息的表名
<users-store> <!-- 注釋掉原來文件存儲的方式 --> <!-- <repository name="LocalUsers" class="org.apache.james.userrepository.UsersFileRepository"> <destination URL="file://var/users/"/> </repository> --> <!-- 改為數(shù)據(jù)庫的方式 --> <repository name="LocalUsers" class="org.apache.james.userrepository.JamesUsersJdbcRepository" destinationURL="db://maildb/mail_users"> <sqlFile>file://conf/sqlResources.xml</sqlFile> </repository> </users-store>
2.、配置數(shù)據(jù)庫信息
找到<data-source>標簽,根據(jù)具體數(shù)據(jù)庫類型進行配置,下面已國產(chǎn)達夢數(shù)據(jù)庫為例
maildb:數(shù)據(jù)源名稱
<data-source name="maildb" class="org.apache.james.util.dbcp.JdbcDataSource"> <driver>dm.jdbc.driver.DmDriver</driver> <dburl>jdbc:dm://127.0.0.1:5236/test_mail</dburl> <user>test</user> <password>test123</password> <max>50</max> </data-source>
3、添加依賴包
因為我用的是達夢數(shù)據(jù)庫,james里面沒有這個數(shù)據(jù)庫的依賴包,所以需要額外添加,如果是mysql、oracle常用的數(shù)據(jù)庫就不需要再額外添加,因為james已經(jīng)支持。
找到j(luò)ames-2.3.2\lib,然后把需要的依賴包放進去
4、創(chuàng)建用戶表
正常情況下會自動創(chuàng)建,sql語句在james-2.3.2\apps\james\conf\sqlResources.xml
如果不會自動創(chuàng)建,那么自己把sql語句復(fù)制出來執(zhí)行
CREATE TABLE "MAIL_USERS" ( "USERNAME" VARCHAR2(64) NOT NULL, "PWDHASH" VARCHAR2(50), "PWDALGORITHM" VARCHAR2(20), "USEFORWARDING" NUMBER(1,0), "FORWARDDESTINATION" VARCHAR2(255), "USEALIAS" NUMBER(1,0), "ALIAS" VARCHAR2(255), PRIMARY KEY("USERNAME") ); COMMENT ON TABLE "MAIL_USERS" IS 'James郵件用戶'; COMMENT ON COLUMN "MAIL_USERS"."PWDALGORITHM" IS '加密方式,默認SHA'; COMMENT ON COLUMN "MAIL_USERS"."PWDHASH" IS '加密后的密碼'; COMMENT ON COLUMN "MAIL_USERS"."USERNAME" IS '郵箱帳號';
2.James密碼是如何加密驗證的
當(dāng)你通過telnet添加新用戶時,比如add user test 123456,你可以查看數(shù)據(jù)庫中的記錄,username字段是test,pwdhash是加密后的密碼,pwdalgorithm字段是“SHA”,顯然用的是SHA加密方式。
讓我們看下james源碼是如何實現(xiàn)的,網(wǎng)上找到apache-james-2.3.2-src.zip源碼文件,版本根據(jù)自己的來,然后用idea打開。
我們找到org.apache.james.userrepository.DefaultUser類
第一個方法verifyPassword()是用來做密碼認證,傳入的參數(shù)是明文密碼,通過DigestUtil.digestString()方法,轉(zhuǎn)換成密文密碼,然后與數(shù)據(jù)庫中密碼作比較,返回比較結(jié)果。請注意這里的DigestUtil.digestString()方法,在后面還在提到。
第二個方法setPassword()是用于密碼轉(zhuǎn)換的,把明文轉(zhuǎn)成密文,用的同樣是DigestUtil.digestString()方法。
讓我們再看下 org.apache.james.security.DigestUtil類,我們可以看到digestString加密的方法。
如果需要在自己的項目里去添加或修改用戶的信息,這時候密碼處理的邏輯肯定需要跟james一致,這時候我們把這個加密的方法拷貝用就行了 。
創(chuàng)建個DigestUtil類,然后調(diào)用DigestUtil.digestString()來獲得加密后的密碼。
package com.mail; import javax.mail.MessagingException; import javax.mail.internet.MimeUtility; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class DigestUtil { public static String digestString(String pass, String algorithm ) throws NoSuchAlgorithmException { MessageDigest md; ByteArrayOutputStream bos; try { md = MessageDigest.getInstance(algorithm); byte[] digest = md.digest(pass.getBytes("iso-8859-1")); bos = new ByteArrayOutputStream(); OutputStream encodedStream = MimeUtility.encode(bos, "base64"); encodedStream.write(digest); return bos.toString("iso-8859-1"); } catch (IOException ioe) { throw new RuntimeException("Fatal error: " + ioe); } catch (MessagingException me) { throw new RuntimeException("Fatal error: " + me); } } private DigestUtil() {} }
加密支持的算法有MD5、SHA、SHA-256等 ,如果你想知道支持哪些算法,可以通過下面的代碼列出所有支持的算法:
import java.security.Security; import java.security.Provider; import java.security.Provider.Service; public class ListAlgorithms { public static void main(String[] args) { for(Provider provider: Security.getProviders()) { for(Service service: provider.getServices()) { if ("MessageDigest".equals(service.getType())) { System.out.println(service.getAlgorithm()); } } } } }
3.總結(jié)
集成java mail直接用明文帳號密碼連接就行了,因為james會自己去加密驗證,其他軟件通過pop3配置,密碼也是用明文就行了。
如果覺得這種連接方式不安全有兩種解決方案:
修改james源碼,比較麻煩。密碼在web端加密,傳輸?shù)阶约汉笈_再解密,然后用解密后的密碼連接james。
import javax.mail.*; import javax.mail.internet.*; import java.util.*; public class SendEmail { public static void main(String[] args) { String host = "smtp.example.com"; // SMTP服務(wù)器地址 String username = "your-username"; // 用戶名 String password = "your-password"; // 密碼 Properties props = new Properties(); props.put("mail.smtp.host", host); props.put("mail.smtp.auth", "true"); Session session = Session.getInstance(props, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); try { Message message = new MimeMessage(session); message.setFrom(new InternetAddress("from@example.com")); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("to@example.com")); message.setSubject("Email Subject"); message.setText("Email Body"); Transport.send(message); System.out.println("Email sent successfully"); } catch (MessagingException e) { throw new RuntimeException("Error sending email", e); } } }
到此這篇關(guān)于Apache James數(shù)據(jù)庫存儲用戶信息的密碼加密問題的文章就介紹到這了,更多相關(guān)Apache James密碼加密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
VScode Remote SSH通過遠程編輯與調(diào)試代碼
這篇文章主要介紹了VScode Remote SSH通過遠程編輯與調(diào)試代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05Ubuntu18.04一次性升級Python所有庫的方法步驟
這篇文章主要介紹了Ubuntu18.04一次性升級Python所有庫的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01解讀Linux下ip命令展示的網(wǎng)絡(luò)連接信息
這篇文章主要給大家介紹了關(guān)于Linux下解讀ip命令展示的網(wǎng)絡(luò)連接信息的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起看看吧。2018-03-03linux實現(xiàn)定時備份mysql數(shù)據(jù)庫的簡單方法
在本篇文章中我們給大家整理了一些關(guān)于linux實現(xiàn)定時備份mysql數(shù)據(jù)庫的簡單方法,有需要的朋友們可以學(xué)習(xí)下。2018-09-09