当前位置: 首页 > 知识库问答 >
问题:

将Oracle身份验证迁移到表

帅雅逸
2023-03-14

我有一个基于Java/Spring的web应用程序,它使用Oracle11g。当前,用户在登录时直接通过用户名/密码对系统表sys.user$进行身份验证。

这不得不改变,所以我们创建了一个(常规的)新表,在那里存储所有的用户数据。我们将所有现有密码插入到新创建的表中。然而,密码似乎是以本站点描述的方式加密/散列的

我使用了ora_hash和dbms_obfuscation_toolkit.desdecrypt,但都没有给我一个正确的结果。我知道用户的正确密码,并且可以看到Oracle为此生成的值,但我无法重现Oracle通常“处理”密码数据的方式。

有没有什么方法可以在不重置所有密码的情况下解决这个问题呢?

共有1个答案

后烨煜
2023-03-14

在注释中调整链接到的Java实现,这很接近,但并不完全正确地使用salt:

import java.security.MessageDigest;
import java.util.Formatter;

class Main{

    public static String calculateHash(String password) throws Exception{
        MessageDigest crypt = MessageDigest.getInstance("SHA-1");

        String encodedPassword = "S:71752CE0530476A8B2E0DD218AE59CB71B211D7E1DB70EE23BFB23BDFD48";

        // Convert password to bytes
        byte[] bPassword = password.getBytes("UTF-8");

        // Get salt from encoded password
        String salt = encodedPassword.substring(42, 62);
        System.out.println("Salt is " + salt);

        // Convert salt from hex back to bytes
        // based on http://stackoverflow.com/a/140861/266304
        int len = salt.length();
        byte[] bSalt = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            bSalt[i / 2] = (byte) ((Character.digit(salt.charAt(i), 16) << 4)
                + Character.digit(salt.charAt(i+1), 16));
        }

        // Add converted salt to password bytes
        // based on http://stackoverflow.com/a/80503/266304
        byte[] bData = new byte[bPassword.length + bSalt.length];
        System.arraycopy(bPassword, 0, bData, 0, bPassword.length);
        System.arraycopy(bSalt, 0, bData, bPassword.length, bSalt.length);

        // Hash the final byte array
        crypt.update(bData);
        byte bHash[] = crypt.digest();

        Formatter formatter = new Formatter();
        for (byte b : bHash)
        {
            formatter.format("%02x", b);
        }

        System.out.println("Expected      " + encodedPassword.substring(2,42));

        return formatter.toString().toUpperCase();
    }

    public static void main(String[] args) throws Exception {
        System.out.println("The result is " + calculateHash("ZK3002"));
    }
}

它给出输出:

Salt is 1DB70EE23BFB23BDFD48
Expected      71752CE0530476A8B2E0DD218AE59CB71B211D7E
The result is 71752CE0530476A8B2E0DD218AE59CB71B211D7E

PL/SQL版本涉及一些转换;dbms_crypto.hash()采用raw参数,因此您必须将纯文本密码转换为raw,然后将提取的salt连接起来--它已经是十六进制的。(在Pete Finnigan的博客中的PL/SQL版本中,您可能会注意到他有一个显式的hextoraw调用,所以我要稍微简化一下)。因此,对于您的示例,传递给dbms_crypto.hash的参数将是zk3002的十六进制(OK,raw)等效值,即5A4B33303032,十六进制盐连接到该值;所以5A4B333030321DB70EE23BFB23BDFD48

您可以将产生的散列与Oracle散列版本进行比较,跳过初始的s:和嵌入的salt。

 类似资料:
  • 我正在尝试将wildfly身份验证迁移到elytron,并且除了一个问题之外,几乎所有内容都可以按照我想要的方式工作。 我们正在使用quartz调度程序运行作业。这些作业不受调用方原则的约束。使用 我能够将原则传播到以下EJB调用。这不再有效,原则始终是“匿名”。有没有一种方法可以对Elytron做同样的事情?

  • 我有一个现有的项目是建立在: AngularJS 我正在重写前端,将其移动到Angular 8,我想利用firebase的功能。 我目前正在集成身份验证功能(用户名/密码、谷歌、twitter、facebook等) 我在考虑我的下一步: 一旦我的使用通过firebase验证,我的GAE PHP后端如何检查用户是否通过了验证 我在想象这样的事情: 一旦通过firebase验证,使用OAuth2令牌调

  • 我正在尝试将Web应用程序从WebSphere 8.5.5迁移到Liberty16.0.0.3。在WebSphere中,我曾经定义了一些J2C安全条目,然后以编程方式加载这些条目。我如何在Liberty中实现这一点? 我尝试在服务器中定义一个“authData”条目。xml,然后通过AuthDataProvider加载它。getAuthData(),但这需要“passwordUtilities-1

  • 使用这个例子,我的连接几乎可以工作 http://blogs.nologin.es/rickyepoderi/index.php?/archives/105-oracle-driver-and-kerberos.html 我使用的是Java7,但使用另一个没有问题。有没有一种方法可以用jvm正确读取票证(参见jdk中的kinit不要创建正确的票证)

  • 我试图在我的rails应用程序中使用LinkedIn的api进行身份验证。我对rails很陌生,所以我遵循了以下指南http://sourcey.com/rails-4-omniauth-using-devise-with-twitter-facebook-and-linkedin/ 耙中止!NameError:main的未定义局部变量或方法'/users/AlexanderKehaya/.rvm

  • 身份验证 PDF版下载 企业应用中的URL链接可以通过OAuth2.0验证接口来获取员工的身份信息。 通过此接口获取员工身份会有一定的时间开销。对于频繁获取员工身份的场景,建议采用如下方案: 企业应用中的URL链接直接填写企业自己的页面地址; 员工跳转到企业页面时,企业校验是否有代表员工身份的cookie,此cookie由企业生成; 如果没有获取到cookie,重定向到OAuth验证链接,获取员工