How to reset Thingworx Administrator User password

Thingworx를 사용하다 보면 시스템 관리자인 Administrator 계정의 비밀번호가 유실되는 경우가 있다.
물론 있어서는 안되는 일이지만,

  • 아주 오래된 프로젝트 VM을 되살려서 확인할 때, 문서화가 되어있지 않거나 문서가 유실된 경우
  • 고객 사이트 정책 상 변경을 권고 받는 경우
  • Admin 계정으로 접속한 개발자가 테스트로 비밀번호를 변경했다가 다시 되돌리지 못하는 경우
    (버전에 따라 첫 세팅시에는 글자 수 제한 없이 설정가능한 경우가 있는데, Composer에서 설정 시에는 글자 수 제한이 적용된다.)

등등.. 여러 이유로 Administrator의 비밀번호는 기상천외하게 유실 될 수 있다.

다년간의 삽질 + PTC TS에서 싫어하는 Thingworx 디컴파일 해체쇼 + Thingworx 베이스의 시스템을 GS 인증 받기 위한 경험을 살려, 긴급하게 Administrator의 비밀번호를 초기화 하기 위한 방법을 작성해보려 한다.
(GS 인증 평가에는 암호 encrypt/decrypt 증명이 필수였다. 문자열을 직접 한단계씩 암호화를 해서 시스템에 저장된 비밀번호랑 같게 나오는지 대조해야 통과할 수 있었다…💦)

⚠️ Thingworx 시스템 DB를 직접 조작하는 것은 시스템에 심각한 오류를 초래할 수 있으므로
비상시 외에는 해당방식을 권장하지 않습니다.

⚠️ Administrator 계정의 비밀번호 Reset 직후 바로 비밀번호를 변경하세요.

⚠️ Thingworx 버전에 따라 로직이 달라질 수 있습니다.
본 글은 Thingworx 8.5에서 테스트 되었었고, Thingworx 9.3의 솔루션 디컴파일을 통해 분석된 글임을 알려드립니다.
(Thingworx 8.5 분석이 너무 옛날이라 가물가물한데 Thingworx 9.3하고도 디테일이 다른거 같기도 합니다.)

Thingworx가 입력된 문자열이 Password와 일치하는지 판단하기 위해 사용하는 정보

먼저 Thingworx가 자격을 검증하는 로직을 간단히 설명하고,
Thingworx에서 자격 검증 시 쓰이는 값들의 저장 위치와
Thingworx에서 관리자가 설정 가능한 비밀번호 옵션에 대해 살펴보겠다.

그리고 이 모든 정보를 토대로 비밀번호를 초기화 하기 위해 어떤 정보를 DB상에서 업데이트 해야하는지 설명할 것이다.

Thingworx에서 자격을 검증 하는 로직

thingworx-platform-common-{version}.jar 라이브러리 내에 있는 com.thingworx.security.authentication 패키지의 AuthenticationUtilities 클래스에서 메인 검증이 진행된다.

입력받은 String 타입의 id, password 값으로 자격을 검증하게 되는데, 대략적인 검증 순서는 다음과 같다.

  1. String의 id를 통해 User 객체 검색
  2. User 객체의 내장 validatePassword 메서드에 String 타입의 password를 파라미터로 전달
  3. validatePassword 메서드는 입력받은 password를 암호화
  4. 입력 받은 password의 암호화 결과와 DB에 저장된 암호가 동일한지 판단

간단하게 얘기하자면, 사용자가 입력한 비밀번호를 암호화 해서 TW에 저장되어있는 비밀번호랑 다른게 있는지 비교하는 방식이다.

Thingworx에서 자격 검증 시 쓰이는 값들의 저장 위치

Thingworx의 유저 정보는 user_model 테이블에 저장된다.
주요 컬럼은 다음과 같다.

  • name : 사용자 ID
  • passwordHash : 암호화된 비밀번호 해시 값
  • passwordHashIterationCount : 비밀번호 해시 반복 횟수
  • passwordHashAlgorithm : 비밀번호 해시 알고리즘(PBKDF2WithHmacSHA512, PBKDF2WithHmacSHA1)
  • passwordHashSaltSizeInBytes : Salt 길이 (바이트 단위)
  • passwordHashSizeInBytes : 해시 결과값의 크기 (바이트 단위)

이 중 passwordHash는 아래와 같은 포멧으로 표시된다.

[Iterations] : [Salt] : [PBKDF2 Encode Result]

포멧을 살펴본 김에 상세한 얘기를 하자면, 사용자가 입력한 비밀번호를 암호화 할 때
입력한 비밀번호 문자열을 Hex로 변환한 passwordHash의 [Salt] 난수를 사용하여,
지정한 Hashing iterations 만큼 반복하며 지정된 키 길이(Hash size in bytes)로 PBKDF2 SHA-512/PBKDF2 SHA-1 변환한다.

Thingworx의 GS 인증 암호 평가쪽 관련 정보

GS 인증을 위한 평가 작업할 때, 암호에 대한 증명을 해야해서 Iterations만 1로 설정한 뒤

  1. **[Salt]**에 해당하는 부분을 온라인 Hex Generator로 변환하고
  2. 온라인 Generate PBKDF2 SHA-512 Hashes Online를 통해 비밀번호 문자열로, 1번 수행 결과인 Hex를 Salt로, Iterations를 1, Key length를 64로 설정하여 Generate Hash 하고
  3. 2번 수행 결과인 Generate Hash의 값과 **[PBKDF2 Encode Result]**에 해당하는 부분을 비교 했을 때 동일한 것을 확인
    하여 SHA-512 이상의 암호화가 적용되어있음을 증명하여 평가를 통과한 경험이 있다.
    (Hex 변환쪽이 공백이나 붙여넣기 시 줄바꿈, 문자 등의 문제인지 아니면 온라인 변환기의 문제인지 자주 말썽이긴 했지만.. 여튼 나와 비슷한 니즈가 있는 사람들에게 도움이 되길 바란다.)

Thingworx에서 관리자가 설정 가능한 비밀번호 옵션

Thingworx는 시스템 설정을 구성할 수 있는 기능을 제공하는 시스템 통합 도구 Subsystem을 제공한다.
User Management Subsystem에서 Thingworx의 비밀번호 암호화 알고리즘과 알고리즘에서 사용되는 몇가지 변수를 설정할 수 있다.
User Management Subsystem는 Monitoring 탭이 아니라 Entity를 검색해서 들어가야 Configuration 수정이 가능하다.

해당 SubSystem의 Configuration 탭으로 접근하여 Password Hash Settings 탭에서 비밀번호 옵션을 설정할 수 있다.

관리자가 선택 가능한 Hashing 알고리즘은 PBKDF2WithHmacSHA512(Default), PBKDF2WithHmacSHA1 두가지이다.

Administrator 비밀번호를 admin 초기화

비밀번호 Reset은 Thingworx의 user_model 테이블에서 Administrator에 해당하는 row를 찾아 특정 문자열로 덮어쓰기 하는 방식으로 진행한다.

⭐ 본 글에서는 admin이란 문자열의 암호화 결과로 덮어쓰기 할 것이다.⭐

이를 위해서는 위의 자격 검증 시 쓰이는 값들과 상세 암호화 절차에 대한 설명을 보면 알겠지만, 덮어쓸 문자열이 정상적으로 검증을 통과하기 위해서는 passwordHash 뿐만 아니라 그 외의 Iteration, Salt, Salt Size, Hash Size, Algorithm 전부 조건을 맞춰 주어야 한다.

아래는 각각 컬럼의 UPDATE 구문이다.

UPDATE user_model SET "passwordHash" = '100000:ecbad5a6dc172f92cddd4743e6b4877724e0c675e6e2fc1c780ab62a2350f115acdbd3c6c582afd297a4c77fb5420520e3f36c2c5e12dbfc5fc9c4f3fc2d616d:6fd6785de35b500fb633ab13be4207dead6c26f922b32610c135f446fea2d4abbce57be9058457cddd4e3944fcf42b804c29dc8939a3c29ca6ac64001d0a982c' WHERE name = 'Administrator';
UPDATE user_model SET "passwordHashAlgorithm" = 'PBKDF2WithHmacSHA512' WHERE name = 'Administrator';
UPDATE user_model SET "passwordHashIterationCount" = 100000 WHERE name = 'Administrator';
UPDATE user_model SET "passwordHashSaltSizeInBytes" = 64 WHERE name = 'Administrator';
UPDATE user_model SET "passwordHashSizeInBytes" = 64 WHERE name = 'Administrator';

컬럼 하나하나 업데이트 했는데, 필요에 맞게 수정해서 쓰길 바란다.
별도로 User Management Subsystem을 수정한 적이 없으면, 기본으로는 passwordHash 만 업데이트 하면 될 듯 하다.

업데이트 후 Administrator 계정은 admin으로 로그인할 수 있다.